Raspberry Pi / Python Based Guidance System

Qt has kind of become it’s own complete operating system. So that’s either a tremendous feature or horrible bloat, depending on your point of view!

Qt also has built in support for parsing NMEA strings and turning new GPS positions into events you can catch in your main loop. This is done through the QPositioning API. The API exposes latitude and longitude, and altitude. However for an AOG-type program, this may not be sufficient (for example PAOGI messages). I’m sure deep inside the Qt hierarchy a class could be extended to cover these needs, but might be too much bother.

Qt is definitely a huge library of available features as I’m finding out! This is the first ever time I’ve done OOP and its certainly been a huge learning curve. I also maybe wasn’t very clear earlier that the threads are done with Qt objects (QThread and QObject tasks) that then use signals and slots to communicated and trigger events in the main thread.

Which NMEA sentence and what parts of the sentence does AgOpenGPS require exactly? Currently I am using the lat/lon E/W, N/S, GPS fixity and No. satellites from the GPGGA message. I plan to use the timestamp as well but what are things such as altitude used for?

Mainly GGA I think (or RMC). There was once the use of a custom, NMEA sentence for things like roll, but I don’t see that in the source anymore.

1 Like

So not made too much progress on the GPS in recent weeks as I have been busy with work and other things. Starting to look now at how to calculate distance from an AB line defined as 2 points. My initial thought is to calculate the euclidean distance from this line to the current position. Is this how AOG calculates cross cross track error?

hello friends, I make some device GPS guidance using phyton and kiwi.

now just show tractor and guidance line, still dont make AB point…

someone have other way to do this project?

Some other way? I’ve found an easy way for good results: download AgOpenGPS and run it on a Windows computer along with an Ardusimple RTK2B (or similar) GNSS receiver and a small interface box. Detailed instructions and support available.

I would like a way where I don’t use windows.

My main reason for wanting to use a Pi based approach is so that the Pi can do more than just GPS. My aim is to have ‘unlimited’ hardware/software functionality similar to proprietary ISOBUS etc. The hardware interfaces on the pi could be used for inputs and outputs such as lights, switches, joysticks, buzzers etc. An example is a joystick could be wired to the Pi and used to control the GPS along with the touchscreen interface. Then the operator selects a different program and can use the joystick to control a hydraulic loader for example. Multiple Pi’s could be set up cheaply to act as a network for things such as wireless implement cameras all displayed through the same touchscreen. That’s just my thoughts on the possibilities that a GPS system on a Pi could offer.

1 Like

So I’ve made a bit more progress with the GPS. I’ve set it up to work out the heading and equation of an AB line. This then used to calculate the euclidean distance/cross track error with a sign value to be left or right. The next step is to use this get the lightbar working in the Qt widget to provide guidance. Hoping to order an F9P by the end of the week to have a go with before setting up a base station.
image

3 Likes

So I managed to get the program fully working so far! It now changes the lightbar depending on the cross track error amount. Although this is a very inaccurate GPS in theory it should just be a case of getting a more accurate signal and then I can fit a screen to a tractor and try it out! Next up I need to iron out a few bugs and neaten up the GUI. I’m then hoping to start developing a 2D map widget to display the data.

image

3 Likes

hello, do you need some help for make this project? we want to see this project finished.

I’d be more than happy to have help with the project and to develop the system with others. I think that collaboration and the sharing of knowledge often produces the greatest results!

how I can help you? have some git?

I don’t currently have a git for it but I could set one up. Currently the code is quite messy and could probably be optimised quite a bit, so it would be great to have some help with that to review it and improve it. The next big steps are probably implementing a 2D map I think using opengl, adding machine widths and offsets to create multiple working lines and figuring out how to send RTCM corrections to the rover board possibly using the same serial connection as the NMEA data stream.

Got my 2 F9P ardusimple simpleRTK2B boards today. All I can say is wow! These little things are insanely good. I’ve only tried one so far by plugging in the radio USB to the Pi (TX1 to RX1 hack) with the main USB connected to U-Center. So easy to customise the board for what you need. Currently I have removed all messages except the GxGGA which I use. Got it running at 5Hz on my GUI and no problems so far, seems to handle it fine which is great. In theory all I need to do now is set the base station up to output RTCM messages and transmit them to the rover pi and then we have a fully function autoguidance (obviously a long way to go for features yet). Even though they cost £200 each, it should be pretty easy to fit along with a touchscreen and pi for less than £400 which would be incredible value for money.

118213867_302119790877243_9037066755502486674_n

2 Likes

Also managed to make a little test set up of an LED light bar. Seems to be working great. The whole system is running with 10Hz from the F9P. The only issue seems to be an issue with RPi.GPIO and PyQt5 as for some reason it seems to forget that the gpio setup has been set to BCM and then crashes. At the moment I have fixed it by repeating the command. A quick google seems to suggest it could be an issue with the Qthreading but I’ll have to have a better look

So not made too much progress with the python side of the script. Mostly been messing around with the F9P’s trying to get rtk to work. Had it working over a local tcp connection and have now just managed to get it working over a forwarded port using str2str on both the base and rover raspberry pis. For some reason rtk2go just won’t work for me with str2str. I’ve tried several things but it just won’t work including emailing SNIP. I also had a small trial with an uncorrected F9P last weekend using ~50m of electric fencing line and then setting my A/B points at the end. I was hugely impressed by the accuracy and repeatability of the F9P within a few minutes before there started to be higher drift. This was all using the python code I’d created and so it was good to see that in principal it is working and a viable system. Still a long way to go though!

1 Like

Done a bit of tidying up today to make the code more correct. I’ve set up 2 more QObject workers and associated threads: One for hardware outputs and one for hardware inputs. So far this seems to overcome the issue of Qthread/RPi.GPIO interaction outside of a thread. The other benifit is that this is setup in advance for hardware inputs such as buttons which would need a thread to run a while loop without locking up the gui or timers. This should be quite handy when testing the pi in a headless format with a button on a joystick to set the A/B line. Hopefully, I’ll get the chance to test that out this weekend along with an RTK fix though we will likely be busy with harvest. I’m still having persistent issues streaming data to rtk2go so I’ve parked that for now and hope to use port forwarding which is more controllable from my point of view.

EDIT: May have spoken a bit too soon on the working Qthreads/RPi.GPIO link. It seems to work better, but it is still getting having issues when stopping the GPS, this should simply clear the LEDs and set them all to blank but it reports an error of GPIO not set to output, even though it is in the worker thread init method. I suspect that the issue is still the same as before and will require some more digging.

2 Likes

Did a bit of investigating about the issue and I think it seems that the issue might be a signal being ‘emitted’ from a thread after a quit function has been called for my thread. My guess is that this signal is being sent before quit is call and is the waiting in a queue whilst the rest of the main thread operations run (other functions after quit) and this is why it is then appearing afterwards and itself triggering a function it is connected to which is where the issue arises. Is there a way to get the main thread to pause/wait for either a set time whilst these other threads do their thing or something else? Any help would be appreciated!

Managed a work around which is to add another if statement to the refresh function which is triggered by the worker thread signal. This can then be toggled as required to further prevent an further actions from occuring after quit has been called.

So another quick update, this evening I thought as I had implemented the hardware input worker I’d try out a button for input. After a bit of trial and error with the code I managed to fairly easily get the code working! I had it set so that a push button operated the set A/B line. This worked really well and I could see how this could be used on a joystick integrated into a tractor armrest to make setting this easier. Need to add a debounce timer or something to further prevent double pressing but that’s easy enough to do.

1 Like