Raspberry Pi / Python Based Guidance System

Hi All,

New to the forum and relatively new to raspberry pi, GPS, electronics etc… I’ve been working on a few agricultural projects so far including including a weather station and animal RFID EID reader. I’ve been looking at AOG for a little while and think that it’s a fantastic development. My reason for wanting to develop a pi/python based system is to go beyond just the GPS aspect and allow for the raspberry pi to be adaptable for many applications such as machine control, implement cameras, farm management, etc… all through a single selectable user interface (Touch screen and controls). I wanted to create a topic for this to follow my progress, gain input and advice and share the process with others.

1 Like

Firstly, I have started with the basics, a simple cheap GPS module using a UART interface. I’ve been looking at parsing the NMEA sentences to get the lat/long values as well as other data such as satellite count. I’ve spoken to youtuber who has developed a pi based GPS system already for advice on python modules. My idea is to create a GUI using PyQt5 with matplotlib to display the GPS position on the touch screen as well as allow the user to input parameters like implement width. To begin with I want to develop a simple system which creates parallel straight AB lines which a user can use to guide the tractor (light bar) before progressing into more detail. For the actual version I intend to use F9P base and rover setups to get the required accuracy (<10cm if possible).

Below is a great python repository with several different examples of steering algorithms (amoungst other things) implemented in python (including Pure Pursuit and Stanley as used in AOG).

3 Likes

Thanks for the link! I appreciate the input and links as I don’t have a lot of information or existing examples to follow.

There is a guy in northern ireland who is doing this. Farm Theory on YouTube. Interesting project.

Yeah, that’s who I’ve spoken to. He was really helpful giving me some initial starting points for how to do various aspects of the GUI, geometry etc and which modules to use. The main difference between his and my starting point is that I plan to use pyQt5 instead of wxPython for the GUI. After doing a bit of research it seems there’s more tutorials on Qt5 and there are also some QUI editors available.

Qt Designer is the standard Widget layout editor, and you can use it with Python. PyQt5 has a module called uic, which you can use to load the .ui files at runtime and create the GUI, rather than have to generate code with pyuic. An example of this is here. It is possible to do the same thing with PySide2 and its QUiLoader class.

However, I feel like QtQuick (QML) is the future of Qt and the the best way to go for this sort of application, especially one that wants to be touch-oriented. This is what I used with QtAOG, and I believe it was the right choice. I’m obviously biased, but I strongly recommend you consider QtQuick (which is part of PyQt anyway).

Python is an interpreted language and as such is an order of magnitude or more slower than C# or C++, but it’s still a good choice, especially for the front end interface stuff. Anything that is too slow for pure python could be put in Cython modules and compiled, and called from interpreted python code. I think this sort of hybrid can work out very well.

1 Like

Using RTKLIB enu (east nouth up) output or F9P RELPOSNED (Nouth East Down) output, 2D plane coordinates with the BASE point as the origin can be obtained, so I made a guide to display on LXterminal with only simple trigonometric functions.
Unfortunately I can’t make GUI software, but it’s still useful for guidance simple parallel lines.

4 Likes

So first update, I have mainly been working on simple things. I have been working on parsing the required information from the $GPGGA NMEA string including lat, long, if their is a GPS fix and the number of satellites. I have also been trying out PyQt5 to create a main GUI window. I have started looking at Qt Designer and Creator to see if these can be used to create a GUI. My next challenge is to convert the lat and long (I believe WGS84) to UTM coordinate for planar geometry. Then I can start trying to plot those coordinates using matplotlib.

There’s a UTM module in PyPi that I’ve used with success.

Also Qt has a built-in API for GPS positioning (parsing NMEA, etc), but I’m not sure if it’s low-level enough for this purpose. But it would be worth looking at. Anything you don’t have to implement is one less area for a bug.

1 Like

After doing some more reading, it seems as though I may run into issues with matplotlib refresh rates at a later date. Therefore, I have decided to shift my focus to using pyQtGraph which is a simpler package and has proven better for live graphing applications. An additional benefit is that it is part of Qt and therefore will hopefully be easier to implement.

I don’t know anything about programming, but this video can help. (I think).

Python library:
https://marvelmind.com/download/

1 Like

Hello Hutchy, I appreciate your effort for the project and would like to know how I could be of some help.
I would like to implement the same system and test in parallel with you, the small ammount of programming skills I have, I can try to implement something, or even help to debug.

Thanks

1 Like

Hi, I’m (actually I can’t take all the credit, there are two of us working on this) working on something similar. Went with a mix of arduinos and a pi; the former to control various components and the latter to bring them all together under one universal controller.

We have gone with Node Red; got AOG as the guidance system and the pi / NR in place of various NodeMCU / ESP32s. These allow remote control / drive motor automation to all be controlled from a mobile phone.

Still struggling with one last aspect of it, will then post up some videos and a breakdown. Right now it’s just too messy to make sense of any pics.

1 Like

Hi @neothingsiot, any help would be greatly appreciated implementing things and debugging. I’d be happy to share the code, through something like github etc though its currently not set up there. Sorry for the late reply, I haven’t been working on it in the past few days (My day job isn’t farming!). Hopefully now I will have some more time to work on it more consistently.

Hello colleagues,

I am from Marvelmind Robotics and the video at the beginning of the conversation was shot by us using our Indoor “GPS”. Thus, we will be happy to answer your questions about the system or integration with Pi or Arduino.

We will be happy to contribute to the topic of autonomous navigation or precise indoor positioning in general, because we have rather deep practical experience with it :slight_smile:

A few other relevant demos or links that may be useful:

Demos of other self-driving robots based on our Indoor “GPS”:

  • I had to remove the links, because I am a new user and there seems to be a 2-link policy. Anyway, you have find many relevant demos on our YouTube channel: autonomous robot examples, autonomous drone examples

As mentioned, we will be happy to answer your additional questions.

BR,
Maxim

So just as an update, I’ve spent some time continuing to read the NMEA strings. I’ve then set up a function which coverts the lat/lon in ddmm.mmm format to decimal with the correct sign for conversion to UTM coordinates. I’ve then used the UTM module to convert thses values to UTM coordinates and zone. I’ve also capture the zone for use later on to ‘force’ the conversion to maintain the same coordinate system conversion if the zone changed. This could then be set at the start of a field to create a basepoint.

I’ve also spent a small amount of time working with Qt. I’ve been playing with the designer to try and understand how to do layouts and set buttons to the sides of the window to allow for consistent scaling etc. My next main challenge is using threading to run the NMEA parsing/conversion as a constant background process which could then trigger the update of the GUI / Plot. So far I have managed to implement the UTM coordinates in the window as text which can be updated, triggered by a push button. Once I have the data threads streaming into the application I should then be able to move onto the pyqtgraph and mapping (using shapely based on advice) to start implementing basic guidance. I’m initially hoping this will be as simple as defining an AB straight line (using push buttons), and then measuring the offset distance for lightbar guidance. Hopefully this can then be scaled to curved lines etc and eventually autosteering!

So another update, I’ve made some pretty good progress over the last week on the project. Firstly I have implemented threading within the QUI to prevent it locking up with a continuous while loop streaming the data in from the UART port. I’ve then also made this thread so that it can be stopped/restarted to allow the GPS to be toggled within the GUI. My main reason for doing this is to allow the used to choose where to set a base point, which then locks in the UTM zone as well as allowing for all subsequent positions to be made relative i.e. 653,653.13421 > 0.134 if that was the base location. I’ve also implemented a simple method for setting A/B straight line coordinates so that this line can then be used as a geometry to define current offset. I’m currently thinking to start simply at first and just allow for Euclidean distance from this point. To provide some really simple guidance which could then be linked to a guide light bar. Hopefully this weekend I will be able to implement some more simple methods into the program to further improve my understanding! Also hoping to order some F9P boards soon to set up a base and rover and get some accurate positions!

2 Likes

Hmm, isn’t there an event-driven serial class in PyQt? I know there is one in C++, which I use. Shouldn’t ever have to block reading bytes from a pipe. According to the docs, QSerialPort should be wrapped by PyQt. Shouldn’t need threading, if you can let the Qt event loop do all the work for you.

Hi Torriem, I didn’t realise that there was a Qt serial class built in called QSerialPort which worked with events. The reason I put the serial reading into a thread was to prevent the GUI hanging with large operations. In the thread itself I’ve put the serial data reading, NMEA parsing and the UTM conversion so that the thread signals back only the GPS fix, No. satellites and the local UTM easting/northing (UTM - the rounded base point). Although this is currently not a lot, my thinking was that this thread worker could then be used to do more heavy processing when I get onto curved lines, field boundaries etc and depending on processing needs also allow for multiprocessing to be implemented.