123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #!/usr/bin/env python
- '''
- calculate GPS lag from DF log
- The DF log file needs to be generated with ATT, GPS and IMU bits:
- - On copter (bit0, bit2 and bit18) set on the LOG_BITMASK parameters
- - On rover (bit0, bit2 and bit7) set on the LOG_BITMASK parameters
- - On plane (bit0, bit2 and bit7) set on the LOG_BITMASK parameters
- Make sure IMU_RAW (bit 19) is not set
- For this to work, the vehicle must move at speeds above the --minspeed parameter (defaults to 6m/s)
- The code really only works when there is significant acceleration as well.
- You'll need to fly quite aggressively on a copter to get a result.
- '''
- from __future__ import print_function
- from builtins import range
- import os
- from argparse import ArgumentParser
- parser = ArgumentParser(description=__doc__)
- parser.add_argument("--plot", action='store_true', default=False, help="plot errors")
- parser.add_argument("--minspeed", type=float, default=6, help="minimum speed")
- parser.add_argument("--gps", default='', help="GPS number")
- parser.add_argument("logs", metavar="LOG", nargs="+")
- args = parser.parse_args()
- from pymavlink import mavutil
- from pymavlink.mavextra import *
- from pymavlink.rotmat import Vector3
- '''
- Support having a $HOME/.pymavlink/mavextra.py for extra graphing functions
- '''
- home = os.getenv('HOME')
- if home is not None:
- extra = os.path.join(home, '.pymavlink', 'mavextra.py')
- if os.path.exists(extra):
- import imp
- mavuser = imp.load_source('pymavlink.mavuser', extra)
- from pymavlink.mavuser import *
- def velocity_error(timestamps, vel, gaccel, accel_indexes, imu_dt, shift=0):
- '''return summed velocity error'''
- sum = 0
- count = 0
- for i in range(0, len(vel)-1):
- dv = vel[i+1] - vel[i]
- da = Vector3()
- for idx in range(1+accel_indexes[i]-shift, 1+accel_indexes[i+1]-shift):
- da += gaccel[idx]
- dt1 = timestamps[i+1] - timestamps[i]
- dt2 = (accel_indexes[i+1] - accel_indexes[i]) * imu_dt
- da *= imu_dt
- da *= dt1/dt2
- #print(accel_indexes[i+1] - accel_indexes[i])
- ex = abs(dv.x - da.x)
- ey = abs(dv.y - da.y)
- sum += 0.5*(ex+ey)
- count += 1
- if count == 0:
- return None
- return sum/count
- def gps_lag(logfile):
- '''work out gps velocity lag times for a log file'''
- print("Processing log %s" % filename)
- mlog = mavutil.mavlink_connection(filename)
- timestamps = []
- vel = []
- gaccel = []
- accel_indexes = []
- ATT = None
- IMU = None
- GPS = None
- dtsum = 0
- dtcount = 0
- while True:
- m = mlog.recv_match(type=['GPS'+args.gps,'IMU','ATT','GPA'+args.gps])
- if m is None:
- break
- t = m.get_type()
- if t.startswith('GPS') and m.Status >= 3 and m.Spd>args.minspeed:
- GPS = m;
- elif t.startswith('GPA') and GPS is not None and GPS.TimeUS == m.TimeUS:
- v = Vector3(GPS.Spd*cos(radians(GPS.GCrs)), GPS.Spd*sin(radians(GPS.GCrs)), GPS.VZ)
- vel.append(v)
- timestamps.append(m.SMS*0.001)
- accel_indexes.append(max(len(gaccel)-1,0))
- elif t == 'ATT':
- ATT = m
- elif t == 'IMU':
- if ATT is not None:
- ga = earth_accel_df(m, ATT)
- ga.z += 9.80665
- gaccel.append(ga)
- if IMU is not None:
- dt = (m.TimeUS - IMU.TimeUS) * 1.0e-6
- dtsum += dt
- dtcount += 1
- IMU = m
- imu_dt = dtsum / dtcount
- print("Loaded %u samples imu_dt=%.3f" % (len(vel), imu_dt))
- besti = -1
- besterr = 0
- delays = []
- errors = []
- for i in range(0,100):
- err = velocity_error(timestamps, vel, gaccel, accel_indexes, imu_dt, shift=i)
- if err is None:
- break
- errors.append(err)
- delays.append(i*imu_dt)
- if besti == -1 or err < besterr:
- besti = i
- besterr = err
- print("Best %u (%.3fs) %f" % (besti, besti*imu_dt, besterr))
- if args.plot:
- import matplotlib.pyplot as plt
- plt.plot(delays, errors, 'bo-')
- x1,x2,y1,y2 = plt.axis()
- plt.axis((x1,x2,0,y2))
- plt.ylabel('Error')
- plt.xlabel('Delay(s)')
- plt.show()
- for filename in args.logs:
- gps_lag(filename)
|