We use some essential cookies to make our website work.

We use optional cookies, as detailed in our cookie policy, to remember your settings and understand how you use our website.

15 posts • Page 1 of 1
Ziggy1982
Posts: 21
Joined: Thu Nov 09, 2023 2:24 am

GPS Stationary Algorithm

Thu Oct 23, 2025 3:56 pm

Hello,
I have an interesting problem. I have a Raspberry Pi 5 with a GPS receiver mounted to a tractor. I am trying to create an algorithm to determine if the tractor is truly moving or is stationary. The complexity comes in with GPS drift. When logging the GPS data, when stationary, I can see the GPVTG message returning speeds in the .1 mph -> 3 mph range. My original approach was too simple, if gps_speed_mph > 1 then isMoving = true. This approach led to many false positives. To further complicate the issue, the tractor could be driving through a field under trees, or may be parked inside a garage, leading to noisy GPS data. I have speed / lat / long / heading /etc available, but need to come up with a reliable algorithm. Here is a dump of some random log data when stationary, parked inside a garage:

Code: Select all

system_date_time	gps_date_time	speed_mph	lat	long	gps_quality	gps_num_sats	distance_traveled_ft	heading	hdop
2025年10月22日T21:52:12.701970+00:00	21:52:12+00:00	0.66	37.02134033	-120.598327	1	7	19.904	64.486	2.26
2025年10月22日T21:53:42.273312+00:00	21:53:42+00:00	0.35	37.02141267	-120.5981348	1	7	15.464	254.497	2.33
2025年10月22日T21:53:04.264424+00:00	21:53:04+00:00	0.97	37.02142317	-120.5980593	1	7	9.194	71.876	2.3
2025年10月22日T21:53:46.274223+00:00	21:53:46+00:00	0.13	37.02140133	-120.5981608	1	7	8.629	241.353	2.33
2025年10月22日T21:53:25.269364+00:00	21:53:25+00:00	0.32	37.0214265	-120.5980785	1	7	7.774	254.121	2.31
2025年10月22日T21:51:53.151844+00:00	21:51:52+00:00	1.02	37.02130767	-120.5984167	1	7	7.664	67.617	2.24
2025年10月22日T21:52:17.703209+00:00	21:52:17+00:00	1.53	37.02135083	-120.5982912	1	7	7.186	63.92	2.26
2025年10月22日T21:55:07.450906+00:00	21:55:07+00:00	0.18	37.0213305	-120.5982068	1	7	7.009	262.012	2.39
2025年10月22日T21:52:58.712870+00:00	21:52:58+00:00	0.4	37.02141467	-120.5980925	1	7	6.792	70.645	2.29
2025年10月22日T21:53:38.272412+00:00	21:53:38+00:00	1.25	37.021424	-120.5980837	1	7	6.678	255.22	2.32
2025年10月22日T21:53:50.275118+00:00	21:53:50+00:00	0.17	37.02139283	-120.5981797	1	6	6.303	240.53	3.3
2025年10月22日T21:50:58.629426+00:00	21:50:58+00:00	0.21	37.02132517	-120.5984745	1	7	6.05	251.253	2.2
2025年10月22日T21:55:20.453969+00:00	21:55:20+00:00	1.01	37.02133633	-120.598229	1	7	5.928	255.13	2.4
2025年10月22日T21:49:11.178277+00:00	21:49:10+00:00	0.21	37.02131317	-120.598494	1	9	5.894	71.336	1.21
2025年10月22日T21:51:29.145976+00:00	21:51:28+00:00	0.78	37.02132217	-120.5984242	1	7	5.768	75.346	2.22
2025年10月22日T21:50:46.626419+00:00	21:50:46+00:00	0.17	37.02133	-120.5984487	1	7	5.201	258.55	2.19
2025年10月22日T21:49:19.180239+00:00	21:49:18+00:00	0.2	37.02132067	-120.5984757	1	7	5.17	61.922	2.13
2025年10月22日T21:55:53.461651+00:00	21:55:53+00:00	0.41	37.02135667	-120.5981983	1	7	5.074	66.706	2.43
2025年10月22日T21:51:58.153052+00:00	21:51:57+00:00	1.45	37.02131467	-120.5984018	1	7	4.746	44.109	2.25
2025年10月22日T21:50:33.623124+00:00	21:50:33+00:00	0.09	37.02132517	-120.5984098	1	7	4.675	265.524	2.18
2025年10月22日T21:52:21.704206+00:00	21:52:21+00:00	1.26	37.0213535	-120.5982765	1	7	4.383	77.158	2.26
2025年10月22日T21:51:43.149294+00:00	21:51:43+00:00	1.37	37.02130517	-120.5984408	1	7	4.332	48.681	2.23
2025年10月22日T21:52:28.705825+00:00	21:52:28+00:00	1.9	37.021362	-120.5982517	1	7	4.17	66.815	2.27
2025年10月22日T21:55:47.460227+00:00	21:55:47+00:00	0.18	37.02135117	-120.5982143	1	7	4.104	59.735	2.43
2025年10月22日T21:52:13.702215+00:00	21:52:13+00:00	0.34	37.02134217	-120.5983133	1	7	4.038	80.431	2.26
2025年10月22日T21:50:08.617066+00:00	21:50:08+00:00	0.81	37.021316	-120.5984188	1	7	4.011	78.617	2.16
2025年10月22日T21:52:55.712159+00:00	21:52:55+00:00	0.51	37.0214085	-120.5981145	1	7	3.82	72.379	2.29
2025年10月22日T21:51:39.148364+00:00	21:51:38+00:00	0.82	37.02129733	-120.598452	1	7	3.655	226.947	2.23
2025年10月22日T21:49:50.187411+00:00	21:49:49+00:00	0.09	37.02131583	-120.598459	1	7	3.574	243.703	2.15
2025年10月22日T21:55:08.451157+00:00	21:55:08+00:00	1.26	37.0213325	-120.598195	1	7	3.522	78.044	2.39
2025年10月22日T21:55:57.462608+00:00	21:55:57+00:00	0.18	37.0213595	-120.5981905	1	7	3.517	69.79	2.43
2025年10月22日T21:53:28.270058+00:00	21:53:28+00:00	0.41	37.02142717	-120.5980682	1	7	3.316	75.081	2.32
2025年10月22日T21:56:01.463641+00:00	21:56:01+00:00	0.55	37.02135833	-120.5982035	1	6	3.164	265.569	7.67
Appreciate the help

gordon77
Posts: 9268
Joined: Sun Aug 05, 2012 3:12 pm

Re: GPS Stationary Algorithm

Thu Oct 23, 2025 4:22 pm

Can you average out the drift over a few readings?

B.Goode
Posts: 18783
Joined: Mon Sep 01, 2014 4:03 pm

Re: GPS Stationary Algorithm

Thu Oct 23, 2025 5:28 pm

Ziggy1982 wrote:
Thu Oct 23, 2025 3:56 pm
I have a Raspberry Pi 5 with a GPS receiver mounted to a tractor. I am trying to create an algorithm to determine if the tractor is truly moving or is stationary. The complexity comes in with GPS drift.

[ ... ]

Appreciate the help

Maybe you have to accept that GPS technology is inherently unreliable with respect to absolute position at any given time. And that as a consequence, since you cannot determine change of position, you cannot calculate speed either.

Perhaps you need recourse to a 'Second Opinion.' An accelerometer maybe?
Beware of the Leopard

Ziggy1982
Posts: 21
Joined: Thu Nov 09, 2023 2:24 am

Re: GPS Stationary Algorithm

Thu Oct 23, 2025 6:39 pm

gordon77 wrote:
Thu Oct 23, 2025 4:22 pm
Can you average out the drift over a few readings?
Potentially, but can you elaborate. How would you define "the drift"?

gordon77
Posts: 9268
Joined: Sun Aug 05, 2012 3:12 pm

Re: GPS Stationary Algorithm

Thu Oct 23, 2025 7:08 pm

Ziggy1982 wrote:
Thu Oct 23, 2025 6:39 pm
gordon77 wrote:
Thu Oct 23, 2025 4:22 pm
Can you average out the drift over a few readings?
Potentially, but can you elaborate. How would you define "the drift"?
I am assuming it's a random error. Try plotting lat and long against time.


terribleted
Posts: 2025
Joined: Tue Oct 06, 2020 8:07 pm

Re: GPS Stationary Algorithm

Thu Oct 23, 2025 8:28 pm

well, pseodo-random error. there is random error (uncertainty) plus changing atmospheric could be a small effect.
differential GPS is an option, but i like the averaging approach.
i have GPS on my camper (RV), and speeds of up to a few miles per hour are occasional when i'm stationary. the camper colllects one/hr.
but you could also ask for 2 in a row above 1 to set the "moving flag". thats way less likely.
The only people that don't make mistakes are people that don't do anything.

scotty101
Posts: 4585
Joined: Fri Jun 08, 2012 6:03 pm

Re: GPS Stationary Algorithm

Fri Oct 24, 2025 8:16 am

This is a common problem and one that has been dealt with by many different industries including agricultural machinery.

As you've discovered a GPS signal is "noisy". The position jumps about but in the long term, the average will be close to your actual position.

Inertial Motion Units (including accelerometers and gyroscopes) have the opposite problem, over the long term they will drift but they are stable in the short term.

The solution is to mathematically combine the data from both to give a more stable and long term accurate position. Kalman filters are common in this area.

Edit: Another solution is odometery. If the wheels aren't turning, you aren't moving. The speed of the wheels is fed in to the navigation algorithm and used to aid the position accuracy

As mentioned above, DGPS can help too.

Another consideration is the position of your antenna. If it is on the end of a long pole held above your tractor and the fields are bumpy and uneven, the antenna can often be tilted +/- 2m either direction from where the wheels are. You need to also take in to account the tilt of the vehicle to adjust for the effect of this.
Last edited by scotty101 on Fri Oct 24, 2025 10:54 am, edited 1 time in total.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

PiGraham
Posts: 5523
Joined: Fri Jun 07, 2013 12:37 pm

Re: GPS Stationary Algorithm

Fri Oct 24, 2025 9:51 am

The time stamps seem erratic.

Code: Select all

2025年10月22日T21:52:55.712159+00:00	21:52:55+00:00	0.51	37.0214085	-120.5981145	1	7	3.82	72.379	2.29
2025年10月22日T21:51:39.148364+00:00	21:51:38+00:00	0.82	37.02129733	-120.598452	1	7	3.655	226.947	2.23
2025年10月22日T21:49:50.187411+00:00	21:49:49+00:00	0.09	37.02131583	-120.598459	1	7	3.574	243.703	2.15
Last time I looked at NMEA data (a long time ago) it was a very steady one report per second.
Is the irregularity on time sue to how you are sampling the data?

It's showing up to 19ft distance in some readings. I would think that if you use a rolling average of position over 10 to 30 seconds the jitter might average out and you can check the displacement between P(T=0) and P(T=20). If you don't need to know position with absolute high accuracy that might do to tell if the tractor is moving or stationary. You might exclude big distance readings, or reading with low gps_quality or low gps_num_stats.

Limit distance values to what makes sense for a tractor.

(削除) All that data shows only one satellite, which is junk data. (削除ここまで) Check the antenna. What do you get with the receiver mounted with a good view of the sky, off the tractor and away from sources of interference?
Last edited by PiGraham on Fri Oct 24, 2025 3:33 pm, edited 1 time in total.

trejan
Posts: 7724
Joined: Tue Jul 02, 2019 2:28 pm

Re: GPS Stationary Algorithm

Fri Oct 24, 2025 11:16 am

PiGraham wrote:
Fri Oct 24, 2025 9:51 am
All that data shows only one satellite, which is junk data.
Those 1s are gps_quality. gps_num_sats is ~7.

PiGraham
Posts: 5523
Joined: Fri Jun 07, 2013 12:37 pm

Re: GPS Stationary Algorithm

Fri Oct 24, 2025 12:04 pm

:lol:

So it is! Headers not aligned. Thanks.
trejan wrote:
Fri Oct 24, 2025 11:16 am
PiGraham wrote:
Fri Oct 24, 2025 9:51 am
All that data shows only one satellite, which is junk data.
Those 1s are gps_quality. gps_num_sats is ~7.

gordon77
Posts: 9268
Joined: Sun Aug 05, 2012 3:12 pm

Re: GPS Stationary Algorithm

Fri Oct 24, 2025 1:07 pm

I tried a cheap USB gps on my pi and I get good results, have you got a reception problem ?

Code: Select all

Location: 34.619266 N 1.0541566 W Time: 13:03:22 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:23 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:24 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:25 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:26 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:27 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:28 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:29 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:30 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:31 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:32 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:33 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:34 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:35 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:36 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:37 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:38 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:39 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:40 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:41 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:42 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:43 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:44 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:45 Date: 25/10/24 Speed: 0.00 Fix: 1
Location: 34.619266 N 1.0541566 W Time: 13:03:46 Date: 25/10/24 Speed: 0.00 Fix: 1

Code: Select all

#!/usr/bin/python3
import serial
import os, sys
import time
import datetime
import re
import shutil
from decimal import *
getcontext().prec = 8
gps_period = 1 # time ,in seconds, between logged gps data
# log data
log = 1 # set log = 1 to log data
# set variables
gpsfound = 2
fix = 0
start = time.time()
gps_data = ""
gps_text = ""
gps_date = ""
gps_time = ""
gps2 = ["?"] * 12
if os.path.exists('/dev/ttyUSB0') == True:
 gpsfound = 0
 ser = serial.Serial('/dev/ttyUSB0',4800,timeout = 10)
elif os.path.exists('/dev/ttyUSB1') == True:
 gpsfound = 1
 ser = serial.Serial('/dev/ttyUSB1',4800,timeout = 10)
while True:
 # read gps data
 if gpsfound < 2:
 try:
 gps_data = ser.readline()
 #print (gps_data)
 if sys.version_info[0] == 3:
 gps_data = gps_data.decode("utf-8","ignore")
 except OSError:
 try:
 fix = 0
 gps_text = ""
 if os.path.exists('/dev/ttyUSB0') == True:
 gpsfound = 0
 ser = serial.Serial('/dev/ttyUSB0',4800,timeout = 10)
 elif os.path.exists('/dev/ttyUSB1') == True:
 gpsfound = 1
 ser = serial.Serial('/dev/ttyUSB1',4800,timeout = 10)
 except OSError:
 pass
 else:
 try:
 fix = 0
 gps_text = ""
 if os.path.exists('/dev/ttyUSB0') == True:
 gpsfound = 0
 ser = serial.Serial('/dev/ttyUSB0',4800,timeout = 10)
 elif os.path.exists('/dev/ttyUSB1') == True:
 gpsfound = 1
 ser = serial.Serial('/dev/ttyUSB1',4800,timeout = 10)
 except OSError:
 pass
 
 # check checksum
 if gps_data[0:1] == "$":
 gps_data = gps_data.rstrip('\n')
 cksum = gps_data[len(gps_data) - 3:]
 chksumdata = re.sub("(\n|\r\n)","", gps_data[gps_data.find("$")+1:gps_data.find("*")])
 csum = 0
 for c in chksumdata:
 csum ^= ord(c)
 if hex(csum) == hex(int(cksum, 16)):
 # check for GPGGA sentences
 if gps_data[1:6] == "GPGGA":
 fix = 0
 gps_data2 = gps_data
 gps1 = gps_data.split(',',12)
 if len(gps_data) > 68 and (gps1[3] == "N" or gps1[3] == "S"):
 fix = int(gps1[6])
 if fix > 0:
 lat1 = int(gps1[2][0:2])
 lat2 = float(gps1[2]) - (lat1*100)
 lat = lat1 + lat2/60 
 lon1 = int(gps1[4][0:3])
 lon2 = float(gps1[4]) - (lon1*100)
 lon = lon1 + lon2/60
 gps_time = gps1[1][0:6]
 gps_text = "Location: "+str(lat)[0:9]+" "+gps1[3]+" "+str(lon)[0:9]+" "+gps1[5]+" Time: "+gps_time[0:2]+":"+gps_time[2:4]+":"+gps_time[4:6]+" Date: "+gps_date[4:6]+"/"+ gps_date[2:4]+"/"+ gps_date[0:2] + " Speed: " + str(gps2[7]) + " Fix: " + str(fix)
 print(gps_text)
 # log data if enabled
 if log == 1 :
 with open("log.txt", "a") as file:
 file.write(gps_text + "\n")
 time.sleep(0.1)
 if fix > 0 and gps_text != "":
 if gps_data[1:6] == "GPRMC":
 gps2 = gps_data.split(',',12)
 gps_date = gps2[9]

hippy
Posts: 19832
Joined: Fri Sep 09, 2011 10:34 pm

Re: GPS Stationary Algorithm

Fri Oct 24, 2025 1:30 pm

I know nothing much about tractors but would the obvious test for being stationary not be that the gear box is in neutral ?

gordon77
Posts: 9268
Joined: Sun Aug 05, 2012 3:12 pm

Re: GPS Stationary Algorithm

Fri Oct 24, 2025 4:58 pm

hippy wrote:
Fri Oct 24, 2025 1:30 pm
I know nothing much about tractors but would the obvious test for being stationary not be that the gear box is in neutral ?
Not if its freewheeling ;)

deepo
Posts: 1439
Joined: Sun Dec 30, 2018 8:36 pm

Re: GPS Stationary Algorithm

Fri Oct 24, 2025 10:26 pm

At work a few years ago I made a prototype GPS application where I used a Moving Average function to dampen the noise of the GPS coordinates. I averaged latitude and longitude separately of course.

15 posts • Page 1 of 1

Return to "Automation, sensing and robotics"

AltStyle によって変換されたページ (->オリジナル) /