From a8eb1f1907b8490baf2ce6a1fb477319d8331f33 Mon Sep 17 00:00:00 2001 From: Mark Snijder Date: Thu, 29 Jun 2017 19:39:49 +0200 Subject: [PATCH 1/3] Reading entire motor configuration instead of every register every time. Increased ax-12a performance 16 times reading 18 servos in 0.05 seconds instead of .9ish. It's supposed to be dynamic, so it works for every motor, although not tested. --- dxl/dxlchain.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/dxl/dxlchain.py b/dxl/dxlchain.py index e5248b0..3c77572 100644 --- a/dxl/dxlchain.py +++ b/dxl/dxlchain.py @@ -427,9 +427,59 @@ def set_configuration(self,conf): self.set_reg(iid,name,val) # if writable set it def dump(self): - """Obtain the motors chain configuration and dumps it on stdout""" conf=self.get_configuration() - print json.dumps(conf,indent=4,sort_keys=False) + dmp = json.dumps(conf,indent=4,sort_keys=False) + print dmp + return dmp + + def get_configuration(self): + """ Gets the current configuration for all motors connected """ + self.get_motor_list(broadcast=broadcast) + + d = OrderedDict() + + for (id, m) in self.motors.items(): + dd = OrderedDict() + d[id] = dd + + length, dump = self._get_configuration(m, id) + + addr = 0 + for value in dump: + name, length = m.getNameByAddr(addr) + if name is not None: + dd[name] = m.registers[name].fromdxl([dump[addr], dump[addr + 1]]) + addr = addr + 1 + + return d + + def _get_configuration(self, motor, id): + with self.lock: + """ Reads all memory addresses of a certain motor """ + offset = 0x00 + length = self._getRegSize(motor) + + checksumed_data = [id, 4, 2, offset, length] + + data = "".join(map(chr, [0xFF, 0xFF] + checksumed_data + [self.checksum(checksumed_data)])) + self.port.write(data) + self.port.flushOutput() + + rec = self._recv() + + return length, rec[1] + + def _get_reg_size(self, motor): + """ Gets the register size of a certain motor type as defined in dxlmotors """ + + minaddr = 0x00 + maxaddr = 0x00 + for reg in motor.registers: + addr = motor.registers[reg].address + (motor.registers[reg].size - 1) + if maxaddr < addr: + maxaddr = addr + + return maxaddr - minaddr def get_motors(self,ids=None): """Return the list of all motors ids, or a specific set, or a single id""" From 8f734485285608df8343e113fc7f95fd40ca62d9 Mon Sep 17 00:00:00 2001 From: Mark Snijder Date: Thu, 29 Jun 2017 19:41:11 +0200 Subject: [PATCH 2/3] Forgot to remove old get configuration. --- dxl/dxlchain.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/dxl/dxlchain.py b/dxl/dxlchain.py index 3c77572..6c36db1 100644 --- a/dxl/dxlchain.py +++ b/dxl/dxlchain.py @@ -375,20 +375,6 @@ def get_motor_list(self,broadcast=True,instantiate=True): delay=time.time()-start logging.debug("get_motor_list delay: %f"%delay) return l - - def get_configuration(self,broadcast=True): - """Obtain the list of motors on a chain, read and return their full configuration""" - self.get_motor_list(broadcast=broadcast) - start=time.time() - d=OrderedDict() - for (id,m) in self.motors.items(): - dd=OrderedDict() - d[id]=dd - for (name,r) in m.registers.items(): - dd[name]=self.get_reg(id,name) - delay=time.time()-start - logging.debug("get_configuration reg delay: %f"%delay) - return d def set_configuration(self,conf): """Compare the motors available on a chain to those specified in the provided configuration, silently try to set all registers, generates an exception if there is a mismatch""" From ce5515dad115bcc18b4fa08f4d95c0bc2b669689 Mon Sep 17 00:00:00 2001 From: Mark Snijder Date: Thu, 29 Jun 2017 19:42:09 +0200 Subject: [PATCH 3/3] Added a method that gets the name of an address. --- dxl/dxlcore.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dxl/dxlcore.py b/dxl/dxlcore.py index c09f6f3..2326cd6 100644 --- a/dxl/dxlcore.py +++ b/dxl/dxlcore.py @@ -61,7 +61,12 @@ def instantiateMotor(cls,id,model_number): mcls=cls.DxlModels[model_number] return mcls() + def getNameByAddr(self, addr): + for name in self.registers: + if self.registers[name].address == addr: + return name, self.registers[name].size + return None, None def getRegisterCmd(self,name): if not name in self.registers.keys():