Skip to content

Commit 58efa90

Browse files
committed
Adds tests and fixes dict objects in channels.
1 parent 3d7c2da commit 58efa90

2 files changed

Lines changed: 96 additions & 7 deletions

File tree

dronekit/lib/__init__.py

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -396,15 +396,47 @@ def decorator(fn):
396396
self.add_attribute_listener(name, fn)
397397
return decorator
398398

399+
400+
class ChannelsOverride(dict):
401+
def __init__(self, vehicle):
402+
self._vehicle = vehicle
403+
self._count = 8 # Fixed by MAVLink
404+
405+
def __getitem__(self, key):
406+
return dict.__getitem__(self, str(key))
407+
408+
def __setitem__(self, key, value):
409+
if not (int(key) >= 0 and int(key) < self._count):
410+
raise Exception('Invalid channel index %s' % key)
411+
dict.__setitem__(self, str(key), value)
412+
self._send()
413+
414+
def __delitem__(self, key):
415+
dict.__delitem__(self, str(key))
416+
self._send()
417+
418+
def __len__(self):
419+
return self._count
420+
421+
def _send(self):
422+
overrides = [0] * 8
423+
for k, v in self.iteritems():
424+
overrides[int(k)-1] = v
425+
self._vehicle._master.mav.rc_channels_override_send(0, 0, *overrides)
426+
427+
399428
class Channels(dict):
400429
"""
401430
Implements RC object.
402431
"""
403432

404433
def __init__(self, vehicle, count):
434+
self._vehicle = vehicle
405435
self._count = count
436+
self._overrides = ChannelsOverride(vehicle)
437+
438+
# populate readback
406439
self._readonly = False
407-
self._overrides = {}
408440
for k in range(0, count):
409441
self[k + 1] = None
410442
self._readonly = True
@@ -413,34 +445,39 @@ def __init__(self, vehicle, count):
413445
def count(self):
414446
return self._count
415447

448+
def __getitem__(self, key):
449+
return dict.__getitem__(self, str(key))
450+
416451
def __setitem__(self, key, value):
417452
if self._readonly:
418453
raise TypeError('__setitem__ is not supported on Channels object')
419-
return dict.__setitem__(self, key, value)
454+
return dict.__setitem__(self, str(key), value)
420455

421456
def __len__(self):
422457
return self._count
423458

424459
def _update_channel(self, channel, value):
425460
# If we have channels on different ports, we expand the Channels
426461
# object to support them.
427-
channel = str(channel)
462+
channel = int(channel)
428463
self._readonly = False
429464
self[channel] = value
430465
self._readonly = True
431-
self._count = max(self._count, int(channel))
466+
self._count = max(self._count, channel)
432467

433468
@property
434469
def overrides(self):
435-
return copy.copy(self._overrides)
470+
return self._overrides
436471

437472
@overrides.setter
438473
def overrides(self, newch):
439-
self._overrides = {}
440474
for k, v in newch.iteritems():
441475
if v:
442476
self._overrides[str(k)] = v
443-
self._master.mav.rc_channels_override_send(0, 0, *list(self._overrides.values()))
477+
else:
478+
del self._overrides[str(k)]
479+
self._overrides._send()
480+
444481

445482
class Vehicle(HasObservers):
446483
"""
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from dronekit import connect
2+
from dronekit.lib import VehicleMode
3+
from pymavlink import mavutil
4+
import time
5+
from dronekit import connect, VehicleMode, LocationGlobal
6+
from dronekit.test import with_sitl
7+
from nose.tools import assert_equals, assert_not_equals
8+
9+
def assert_readback(vehicle, values):
10+
i = 10
11+
while i > 0:
12+
time.sleep(.1)
13+
i -= .1
14+
for k, v in values.iteritems():
15+
if vehicle.channels[k] != v:
16+
continue
17+
break
18+
if i <= 0:
19+
raise Exception('Did not match in channels readback %s' % values)
20+
21+
@with_sitl
22+
def test_timeout(connpath):
23+
vehicle = connect(connpath, wait_ready=True)
24+
25+
assert_equals(len(vehicle.channels), 8)
26+
assert_equals(len(vehicle.channels.overrides), 8)
27+
28+
assert_equals(sorted(vehicle.channels.keys()), [str(x) for x in range(1, 9)])
29+
assert_equals(sorted(vehicle.channels.overrides.keys()), [])
30+
31+
assert_equals(type(vehicle.channels['1']), int)
32+
assert_equals(type(vehicle.channels['2']), int)
33+
assert_equals(type(vehicle.channels['7']), int)
34+
assert_equals(type(vehicle.channels['8']), int)
35+
assert_equals(type(vehicle.channels[1]), int)
36+
assert_equals(type(vehicle.channels[2]), int)
37+
assert_equals(type(vehicle.channels[7]), int)
38+
assert_equals(type(vehicle.channels[8]), int)
39+
40+
vehicle.channels.overrides = {'1': 1010}
41+
assert_readback(vehicle, {'1': 1010})
42+
43+
vehicle.channels.overrides = {'2': 1020}
44+
assert_readback(vehicle, {'1': 1500, '2': 1010})
45+
46+
vehicle.channels.overrides['1'] = 1010
47+
assert_readback(vehicle, {'1': 1010, '2': 1020})
48+
49+
del vehicle.channels.overrides['1']
50+
assert_readback(vehicle, {'1': 1500, '2': 1020})
51+
52+
vehicle.close()

0 commit comments

Comments
 (0)