Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/tridge/pymavlink
Browse files Browse the repository at this point in the history
  • Loading branch information
jgoppert committed Apr 19, 2012
2 parents 8725358 + bb7728a commit 30d289e
Show file tree
Hide file tree
Showing 17 changed files with 1,244 additions and 92 deletions.
13 changes: 12 additions & 1 deletion message_definitions/v0.9/ardupilotmega.xml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@
<field name="breach_time" type="uint32_t">time of last breach in milliseconds since boot</field>
</message>

<message name="DCM" id="163">
<message name="AHRS" id="163">
<description>Status of DCM attitude estimator</description>
<field type="float" name="omegaIx">X gyro drift estimate rad/s</field>
<field type="float" name="omegaIy">Y gyro drift estimate rad/s</field>
Expand Down Expand Up @@ -255,5 +255,16 @@
<field type="uint16_t" name="Vcc">board voltage (mV)</field>
<field type="uint8_t" name="I2Cerr">I2C error count</field>
</message>

<message name="RADIO" id="166">
<description>Status generated by radio</description>
<field type="uint8_t" name="rssi">local signal strength</field>
<field type="uint8_t" name="remrssi">remote signal strength</field>
<field type="uint8_t" name="txbuf">how full the tx buffer is as a percentage</field>
<field type="uint8_t" name="noise">background noise level</field>
<field type="uint8_t" name="remnoise">remote background noise level</field>
<field type="uint16_t" name="rxerrors">receive errors</field>
<field type="uint16_t" name="fixed">count of error corrected packets</field>
</message>
</messages>
</mavlink>
21 changes: 19 additions & 2 deletions message_definitions/v1.0/ardupilotmega.xml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
<field name="focus_lock" type="uint8_t">0: unlock focus or keep unlocked, 1: lock focus or keep locked, 3: re-lock focus</field>
<field name="shot" type="uint8_t">0: ignore, 1: shot or start filming</field>
<field name="command_id" type="uint8_t">Command Identity (incremental loop: 0 to 255)//A command sent multiple times will be executed or pooled just once</field>
<field name="extra_param" type="uint8">Extra parameters enumeration (0 means ignore)</field>
<field name="extra_param" type="uint8_t">Extra parameters enumeration (0 means ignore)</field>
<field name="extra_value" type="float">Correspondent value to given extra_param</field>
</message>

Expand Down Expand Up @@ -226,7 +226,7 @@
<field name="breach_time" type="uint32_t">time of last breach in milliseconds since boot</field>
</message>

<message name="DCM" id="163">
<message name="AHRS" id="163">
<description>Status of DCM attitude estimator</description>
<field type="float" name="omegaIx">X gyro drift estimate rad/s</field>
<field type="float" name="omegaIy">Y gyro drift estimate rad/s</field>
Expand All @@ -249,5 +249,22 @@
<field type="float" name="ygyro">Angular speed around Y axis rad/s</field>
<field type="float" name="zgyro">Angular speed around Z axis rad/s</field>
</message>

<message name="HWSTATUS" id="165">
<description>Status of key hardware</description>
<field type="uint16_t" name="Vcc">board voltage (mV)</field>
<field type="uint8_t" name="I2Cerr">I2C error count</field>
</message>

<message name="RADIO" id="166">
<description>Status generated by radio</description>
<field type="uint8_t" name="rssi">local signal strength</field>
<field type="uint8_t" name="remrssi">remote signal strength</field>
<field type="uint8_t" name="txbuf">how full the tx buffer is as a percentage</field>
<field type="uint8_t" name="noise">background noise level</field>
<field type="uint8_t" name="remnoise">remote background noise level</field>
<field type="uint16_t" name="rxerrors">receive errors</field>
<field type="uint16_t" name="fixed">count of error corrected packets</field>
</message>
</messages>
</mavlink>
7 changes: 5 additions & 2 deletions pymavlink/examples/flightmodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,20 @@ def flight_modes(logfile):
mode = -1
nav_mode = -1

filesize = os.path.getsize(filename)

while True:
m = mlog.recv_match(type='SYS_STATUS',
condition='SYS_STATUS.mode != %u or SYS_STATUS.nav_mode != %u' % (mode, nav_mode))
if m is None:
return
mode = m.mode
nav_mode = m.nav_mode
print('%s MAV.flightmode=%-12s mode=%u nav_mode=%u (MAV.timestamp=%u)' % (
pct = (100.0 * mlog.f.tell()) / filesize
print('%s MAV.flightmode=%-12s mode=%u nav_mode=%u (MAV.timestamp=%u %u%%)' % (
time.asctime(time.localtime(m._timestamp)),
mlog.flightmode,
mode, nav_mode, m._timestamp))
mode, nav_mode, m._timestamp, pct))

for filename in args:
flight_modes(filename)
Expand Down
68 changes: 68 additions & 0 deletions pymavlink/examples/gpslock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python

'''
show GPS lock events in a MAVLink log
'''

import sys, time, os

# allow import from the parent directory, where mavlink.py is
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))

from optparse import OptionParser
parser = OptionParser("gpslock.py [options]")
parser.add_option("--mav10", action='store_true', default=False, help="Use MAVLink protocol 1.0")

(opts, args) = parser.parse_args()

if opts.mav10:
os.environ['MAVLINK10'] = '1'
import mavutil

if len(args) < 1:
print("Usage: gpslock.py [options] <LOGFILE...>")
sys.exit(1)

def lock_time(logfile):
'''work out gps lock times for a log file'''
print("Processing log %s" % filename)
mlog = mavutil.mavlink_connection(filename)

locked = False
start_time = 0.0
total_time = 0.0
t = None
m = mlog.recv_match(type='GPS_RAW')
unlock_time = time.mktime(time.localtime(m._timestamp))

while True:
m = mlog.recv_match(type='GPS_RAW')
if m is None:
if locked:
total_time += time.mktime(t) - start_time
if total_time > 0:
print("Lock time : %u:%02u" % (int(total_time)/60, int(total_time)%60))
return total_time
t = time.localtime(m._timestamp)
if m.fix_type == 2 and not locked:
print("Locked at %s after %u seconds" % (time.asctime(t),
time.mktime(t) - unlock_time))
locked = True
start_time = time.mktime(t)
elif m.fix_type == 1 and locked:
print("Lost GPS lock at %s" % time.asctime(t))
locked = False
total_time += time.mktime(t) - start_time
unlock_time = time.mktime(t)
elif m.fix_type == 0 and locked:
print("Lost protocol lock at %s" % time.asctime(t))
locked = False
total_time += time.mktime(t) - start_time
unlock_time = time.mktime(t)
return total_time

total = 0.0
for filename in args:
total += lock_time(filename)

print("Total time locked: %u:%02u" % (int(total)/60, int(total)%60))
138 changes: 138 additions & 0 deletions pymavlink/examples/magfit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/usr/bin/env python

'''
fit best estimate of magnetometer offsets
'''

import sys, time, os, math

# allow import from the parent directory, where mavlink.py is
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))

from optparse import OptionParser
parser = OptionParser("magfit.py [options]")
parser.add_option("--no-timestamps",dest="notimestamps", action='store_true', help="Log doesn't have timestamps")
parser.add_option("--condition",dest="condition", default=None, help="select packets by condition")
parser.add_option("--noise", type='float', default=0, help="noise to add")
parser.add_option("--mav10", action='store_true', default=False, help="Use MAVLink protocol 1.0")

(opts, args) = parser.parse_args()

if opts.mav10:
os.environ['MAVLINK10'] = '1'
import mavutil
from rotmat import Vector3

if len(args) < 1:
print("Usage: magfit.py [options] <LOGFILE...>")
sys.exit(1)

def noise():
'''a noise vector'''
from random import gauss
v = Vector3(gauss(0, 1), gauss(0, 1), gauss(0, 1))
v.normalize()
return v * opts.noise

def select_data(data):
ret = []
counts = {}
for d in data:
mag = d
key = "%u:%u:%u" % (mag.x/20,mag.y/20,mag.z/20)
if key in counts:
counts[key] += 1
else:
counts[key] = 1
if counts[key] < 3:
ret.append(d)
print(len(data), len(ret))
return ret

def radius(mag, offsets):
'''return radius give data point and offsets'''
return (mag + offsets).length()

def radius_cmp(a, b, offsets):
'''return radius give data point and offsets'''
diff = radius(a, offsets) - radius(b, offsets)
if diff > 0:
return 1
if diff < 0:
return -1
return 0

def sphere_error(p, data):
from scipy import sqrt
x,y,z,r = p
ofs = Vector3(x,y,z)
ret = []
for d in data:
mag = d
err = r - radius(mag, ofs)
ret.append(err)
return ret

def fit_data(data):
import numpy, scipy
from scipy import optimize

p0 = [0.0, 0.0, 0.0, 0.0]
p1, ier = optimize.leastsq(sphere_error, p0[:], args=(data))
if not ier in [1, 2, 3, 4]:
raise RuntimeError("Unable to find solution")
return (Vector3(p1[0], p1[1], p1[2]), p1[3])

def magfit(logfile):
'''find best magnetometer offset fit to a log file'''

print("Processing log %s" % filename)
mlog = mavutil.mavlink_connection(filename, notimestamps=opts.notimestamps)

data = []

last_t = 0
offsets = Vector3(0,0,0)

# now gather all the data
while True:
m = mlog.recv_match(condition=opts.condition)
if m is None:
break
if m.get_type() == "SENSOR_OFFSETS":
# update current offsets
offsets = Vector3(m.mag_ofs_x, m.mag_ofs_y, m.mag_ofs_z)
if m.get_type() == "RAW_IMU":
mag = Vector3(m.xmag, m.ymag, m.zmag)
# add data point after subtracting the current offsets
data.append(mag - offsets + noise())

print("Extracted %u data points" % len(data))
print("Current offsets: %s" % offsets)

data = select_data(data)

# do an initial fit with all data
(offsets, field_strength) = fit_data(data)

for count in range(3):
# sort the data by the radius
data.sort(lambda a,b : radius_cmp(a,b,offsets))

print("Fit %u : %s field_strength=%6.1f to %6.1f" % (
count, offsets,
radius(data[0], offsets), radius(data[-1], offsets)))

# discard outliers, keep the middle 3/4
data = data[len(data)/8:-len(data)/8]

# fit again
(offsets, field_strength) = fit_data(data)

print("Final : %s field_strength=%6.1f to %6.1f" % (
offsets,
radius(data[0], offsets), radius(data[-1], offsets)))

total = 0.0
for filename in args:
magfit(filename)
Loading

0 comments on commit 30d289e

Please sign in to comment.