The Combine Forum

The Combine Forum (
-   Technology (
-   -   DIY AutoSteer with AgOpenGPS (

BrianTee 04-14-2017 11:49 AM

DIY AutoSteer with AgOpenGPS
So i thought i would start a topic that concerns just with AutoSteer. Hardware/software be it PI or arduino, is self contained and only uses AgOpenGPS for some parameters. In fact any front end could generate the ABLine or Contour data for it.

AgOpenGPS sends out 9 bytes on the autosteer port.

Header - 2 bytes - Signed integer, value 32766 or 127 high byte + 254 low byte. Purpose: As a header for upcoming sentence.

Relay Control - 1 byte - Byte, value 0 to 255 defines how many of the 8 sections required to be on. bit 0 LSB is section 1, bit 7 MSB, section 8.
Example 0000 0011 (3) -> Section #1 and Section #2 are on, Sections 3 thru 8 are off

Speed - 1 byte - Byte value 0 to 255, speed in km/h * 4.0.

DistanceFromGuidanceLine - 2 bytes - Signed integer, high byte then low byte. Value is in millimeters from guidance line. Positive denotes right side of line, Negative denotes left side of line.
Special numbers, if value is:
32020, it means autosteer in AgOpenGPS is turned off.
32000 means Autosteer is on but there is no guidance line to calculate a distance from.

HeadingError - 2 bytes - Signed integer, high byte then low byte. Value is in radians * 10,000.
Positive denotes heading toward the guidance line, Negative denotes heading away from guidance line.

PID gain value byte. The LSB bit 0 --> 0 means decrease, 1 means increase
Bits 1 thru 7 are the individual gains or parameters.
Bit 1 - Proportional gain
Bit 2 - Integral gain
Bit 3 - Derivative gain
Bit 4 - Overall gain

The use of binary rather then text means it isn't readable to humans, is more complex, but is much faster. The header bytes allow showing the start of new information. Accurate consistent data is important and since its just a stream of bytes, its important to know where the sentence starts. The GPS Data window in AgOpenGPS shows what is being sent. I will edit this page as required to reflect any changes in sentence structure.

BrianTee 04-14-2017 11:52 AM

So to jump right in, start at the beginning, getting the right information....

Here is some Arduino code for discussion on parsing the sentence.


void setup() { setup here }

void loop()
  // header high/low, relay byte, speed byte, high distance, low distance, high delta, low delta

  if (Serial.available() > 0 & !isHeaderFound) //find the header, 127H + 254L = 32766
    int temp =;
    header = tempHeader << 8 | temp;              //high,low bytes to make int
    tempHeader = temp;                            //save for next time
    if (header == 32766) isHeaderFound = true;    //Do we have a match?
  //Header has been found, presumably the next 6 bytes are the data
  if (Serial.available()> 5 & isHeaderFound)
        relay =;  // read relay control from AgOpenGPS
        speeed =;  //single byte
        distanceError = (float)( << 8 |;  //high,low bytes   
        headingError = (float)( << 8 |;    //high low bytes
        isHeaderFound = false;
        isDataReady = true;             
  if (isDataReady)
..... We have solid data, and we know its the most current so do the next PID loop

} //end of main arduino loop

Is this a good way to take a stream of numbers, find the start of them - consistently, load up the stream into variables, and then and only then allow the module to process data to control the autosteer loop? It is non blocking in any way, even if the port is disconnected it won't go wild because it always needs new data set to true to do the PID loop, and won't get locked up if no new data arrives. Seems to work very well.

Btw, speed is speeed as a variable because speed is an Arduino keyword.

teseler 04-14-2017 02:09 PM

In order to work right, I think that the Integral and Derivative part of the calculation needs to be done at a fixed frequency, you can't do 10 times/sec once, and then only 2times/sec, because the value of the Kd and Ki loose "consistency". If you can live without the integral part, then no problem (I'm starting without it). Maybe a way to solve it is to disconnect autosteering after 1sec of invalid data? I think it can also be good to add a "stop autosteering" input, so you can stop it with a foot switch or something.

BrianTee 04-14-2017 03:28 PM

You should be getting data every 200 msec with a 5 hz nmea and 100 with a 10 hz. The only time you miss data is if something went really wrong, but 99.99% of the time it should just be there.

In good programming though, that is the easy part, the actual program, the hard part is anticipating all the things that can go wrong and be able to handle them gracefully.

CQuick 04-14-2017 04:39 PM

I think there is merit to separating the maths and the control elements.
I.e, the PID loop/Fuzzy inference system produces a desired steering angle at the whatever rate it receives the data. If it misses a packet, no problem, just let the control loop get on with the latest good data. If more than 1s worth of packets dropped, kill the output.
This desired steering angle is then acted upon in the control loop, which compares it against the measured steering angle and outputs appropriate PWM to the valve. This happens quite quickly, say at 25Hz. Any faster and I think the valve would struggle to react in time.

BrianTee 04-14-2017 05:16 PM

I think the oscillating frequency of the steering system is probably around 1 hz. Basic PID theory says we need a sampling frequency at ten times that as a minimum, or 10 hz. Its going to take some tricky math to get it stable with a 5 hz nmea signal.

torriem 04-14-2017 10:42 PM

A kalman filter could fill in the missing steps and get your a workable 10 Hz signal perhaps. In fact I suspect a kalman filter on the input is going to be required.

BrianTee 04-15-2017 10:16 AM

1 Attachment(s)
Teseler, here is that arduino code, it is in no way complete and really is just a bunch of ideas. I have to be careful if i make a change in one, changes are made in the other program and have both uploaded at once.

MountainviewTruck 04-15-2017 11:11 AM

You guys are brilliant. I am a total greenhorn when it comes to GPS and auto-steer. I know nothing about nothing, and would love to know more than that! I left the ag dealer back in 2000, when precision farming was in it's infancy. I don't want to hijack this thread, but can you point me in a direction of where I can start to learn?

Wedge 04-16-2017 01:03 AM


Good idea with the new thread. Should keep the AOG thread cleaner since we are working on a slightly different stage now!

A couple questions for anyone:

-Will it hurt anything if, rather than computing the PID on a timing, we just ran it every time we got new information? Potentially a little more wild depending on data? This leads into filtering the output......

-What is everyone using to dial in their coefficients in the controller? I have put together a PID controller that I have just been running on the Ardunio w/AOG and watching the writeback values to AOG while steering. Gets a rough approximation, until I can put together a physical control system.

-Should we as a group decide on a specific output format(or two) from the control system? Maybe pwm? Range? Are we checking a steering sensor? Specifics help in design!

One more for Brian:

Is it necessary to have both a section control and an autosteer communication option in AOG if the section control is sent through the autosteer as well? Maybe wrap them into one? Or are we looking ahead to $$$$ unlocks here? Hahaha!

All times are GMT -4. The time now is 11:55 PM.

Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.

vBulletin Security provided by vBSecurity v2.2.2 (Pro) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.
User Alert System provided by Advanced User Tagging v3.1.0 (Pro) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.