Skip to content

Commit 7434215

Browse files
committed
Implement remote param updates
1 parent 17a69b3 commit 7434215

File tree

1 file changed

+42
-26
lines changed

1 file changed

+42
-26
lines changed

cflib/crazyflie/param.py

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,16 @@
6262
MISC_CHANNEL = 3
6363

6464
MISC_SETBYNAME = 0
65+
MISC_VALUE_UPDATED = 1
6566
MISC_GET_EXTENDED_TYPE = 2
66-
67-
PersistentParamState = namedtuple('PersistentParamState', 'is_stored default_value stored_value')
68-
6967
MISC_PERSISTENT_STORE = 3
7068
MISC_PERSISTENT_GET_STATE = 4
7169
MISC_PERSISTENT_CLEAR = 5
7270
MISC_GET_DEFAULT_VALUE = 6
7371

72+
PersistentParamState = namedtuple('PersistentParamState', 'is_stored default_value stored_value')
73+
74+
7475
# One element entry in the TOC
7576

7677

@@ -186,32 +187,39 @@ def _check_if_all_updated(self):
186187

187188
def _param_updated(self, pk):
188189
"""Callback with data for an updated parameter"""
190+
191+
# This method handles both param value packets as well as misc param updated packets
192+
# The Misc packets have a command byte first and the variable id is shifted one byte
193+
# Misc packets are not supported for V1
194+
if pk.channel == MISC_CHANNEL:
195+
id_index = 1
196+
else:
197+
id_index = 0
198+
189199
if self._useV2:
190-
var_id = struct.unpack('<H', pk.data[:2])[0]
200+
var_id = struct.unpack('<H', pk.data[id_index:id_index + 2])[0]
191201
else:
192202
var_id = pk.data[0]
193203
element = self.toc.get_element_by_id(var_id)
194204
if element:
195205
if self._useV2:
196-
s = struct.unpack(element.pytype, pk.data[2:])[0]
206+
value = struct.unpack(element.pytype, pk.data[id_index + 2:])[0]
197207
else:
198-
s = struct.unpack(element.pytype, pk.data[1:])[0]
199-
s = s.__str__()
208+
value = struct.unpack(element.pytype, pk.data[1:])[0]
209+
value_s = value.__str__()
200210
complete_name = '%s.%s' % (element.group, element.name)
201211

202212
# Save the value for synchronous access
203213
if element.group not in self.values:
204214
self.values[element.group] = {}
205-
self.values[element.group][element.name] = s
215+
self.values[element.group][element.name] = value_s
206216

207217
logger.debug('Updated parameter [%s]' % complete_name)
208218
if complete_name in self.param_update_callbacks:
209-
self.param_update_callbacks[complete_name].call(
210-
complete_name, s)
219+
self.param_update_callbacks[complete_name].call(complete_name, value_s)
211220
if element.group in self.group_update_callbacks:
212-
self.group_update_callbacks[element.group].call(
213-
complete_name, s)
214-
self.all_update_callback.call(complete_name, s)
221+
self.group_update_callbacks[element.group].call(complete_name, value_s)
222+
self.all_update_callback.call(complete_name, value_s)
215223

216224
# Once all the parameters are updated call the
217225
# callback for "everything updated"
@@ -596,7 +604,7 @@ def __init__(self, cf, useV2, updated_callback):
596604
self.request_queue = Queue()
597605
self.cf.add_port_callback(CRTPPort.PARAM, self._new_packet_cb)
598606
self._should_close = False
599-
self._req_param = -1
607+
self._lock_pattern = None
600608

601609
def close(self):
602610
# First empty the queue from all packets
@@ -627,22 +635,28 @@ def _new_packet_cb(self, pk):
627635
"""Callback for newly arrived packets"""
628636
if pk.channel == READ_CHANNEL or pk.channel == WRITE_CHANNEL:
629637
if self._useV2:
630-
var_id = struct.unpack('<H', pk.data[:2])[0]
638+
release_pattern = pk.data[:2]
631639
if pk.channel == READ_CHANNEL:
632640
pk.data = pk.data[:2] + pk.data[3:]
633641
else:
634-
var_id = pk.data[0]
635-
if (pk.channel != TOC_CHANNEL and self._req_param == var_id and
642+
release_pattern = pk.data[:1]
643+
644+
if (pk.channel != TOC_CHANNEL and self._lock_pattern == release_pattern and
636645
pk is not None):
637646
self.updated_callback(pk)
638-
self._req_param = -1
647+
self._lock_pattern = None
639648
try:
640649
self.wait_lock.release()
641650
except Exception:
642651
pass
643652
elif pk.channel == MISC_CHANNEL:
644-
command = struct.unpack('<H', pk.data[:2])[0]
645-
if self._req_param == command:
653+
command = pk.data[0]
654+
if command == MISC_VALUE_UPDATED:
655+
self.updated_callback(pk)
656+
657+
release_pattern = pk.data[:3]
658+
if self._lock_pattern == release_pattern:
659+
self._lock_pattern = None
646660
self.wait_lock.release()
647661

648662
def request_param_update(self, var_id):
@@ -663,12 +677,14 @@ def run(self):
663677
self.wait_lock.acquire()
664678
if self.cf.link:
665679
if self._useV2:
666-
self._req_param = struct.unpack('<H', pk.data[:2])[0]
667-
self.cf.send_packet(
668-
pk, expected_reply=(tuple(pk.data[:2])))
680+
if pk.channel == MISC_CHANNEL:
681+
self._lock_pattern = pk.data[:3]
682+
else:
683+
self._lock_pattern = pk.data[:2]
684+
685+
self.cf.send_packet(pk, expected_reply=(tuple(self._lock_pattern)))
669686
else:
670-
self._req_param = pk.data[0]
671-
self.cf.send_packet(
672-
pk, expected_reply=(tuple(pk.data[:1])))
687+
self._lock_pattern = pk.data[:1]
688+
self.cf.send_packet(pk, expected_reply=(tuple(pk.data[:1])))
673689
else:
674690
self.wait_lock.release()

0 commit comments

Comments
 (0)