Source code for pypot.dynamixel.io.io

import itertools

from .abstract_io import (AbstractDxlIO, _DxlControl,
                          _DxlAccess, DxlTimeoutError)
from .. import conversion as conv
from ..protocol import v1 as v1


[docs]class DxlIO(AbstractDxlIO): _protocol = v1
[docs] def factory_reset(self): """ Reset all motors on the bus to their factory default settings. """ try: self._send_packet(self._protocol.DxlResetPacket()) except DxlTimeoutError: pass
[docs] def get_control_mode(self, ids): """ Gets the mode ('joint' or 'wheel') for the specified motors. """ to_get_ids = [id for id in ids if id not in self._known_mode] limits = self.get_angle_limit(to_get_ids, convert=False) modes = ['wheel' if limit == (0, 0) else 'joint' for limit in limits] self._known_mode.update(zip(to_get_ids, modes)) return tuple(self._known_mode[id] for id in ids)
[docs] def set_wheel_mode(self, ids): """ Sets the specified motors to wheel mode. """ self.set_control_mode(dict(zip(ids, itertools.repeat('wheel'))))
[docs] def set_joint_mode(self, ids): """ Sets the specified motors to joint mode. """ self.set_control_mode(dict(zip(ids, itertools.repeat('joint'))))
[docs] def set_control_mode(self, mode_for_id): models = [] for m in self.get_model(list(mode_for_id.keys())): if m.startswith('MX'): models += ['MX'] elif m.startswith('SR'): models += ['SR'] else: models += ['*'] pos_max = [conv.position_range[m][0] for m in models] limits = ((0, 0) if mode == 'wheel' else (0, pos_max[i] - 1) for i, mode in enumerate(mode_for_id.itervalues())) self._set_angle_limit(dict(zip(mode_for_id.keys(), limits)), convert=False) self._known_mode.update(mode_for_id.items())
[docs] def set_angle_limit(self, limit_for_id, **kwargs): """ Sets the angle limit to the specified motors. """ convert = kwargs['convert'] if 'convert' in kwargs else self._convert if 'wheel' in self.get_control_mode(limit_for_id.keys()): raise ValueError('can not change the angle limit of a motor in wheel mode') if (0, 0) in limit_for_id.values(): raise ValueError('can not set limit to (0, 0)') self._set_angle_limit(limit_for_id, convert=convert)
# MARK: - Generate the accessors def _add_control(name, address, length=2, nb_elem=1, access=_DxlAccess.readwrite, models=set(conv.dynamixelModels.values()), dxl_to_si=lambda val, model: val, si_to_dxl=lambda val, model: val, getter_name=None, setter_name=None): control = _DxlControl(name, address, length, nb_elem, access, models, dxl_to_si, si_to_dxl, getter_name, setter_name) DxlIO._generate_accessors(control) _add_control('model', address=0x00, access=_DxlAccess.readonly, dxl_to_si=conv.dxl_to_model) _add_control('firmware', address=0x02, length=1, access=_DxlAccess.readonly) _add_control('id', address=0x03, length=1, access=_DxlAccess.writeonly, setter_name='change_id') _add_control('baudrate', address=0x04, length=1, access=_DxlAccess.writeonly, setter_name='change_baudrate', si_to_dxl=conv.baudrate_to_dxl) _add_control('return delay time', address=0x05, length=1, dxl_to_si=conv.dxl_to_rdt, si_to_dxl=conv.rdt_to_dxl) _add_control('angle limit', address=0x06, nb_elem=2, dxl_to_si=lambda value, model: (conv.dxl_to_degree(value[0], model), conv.dxl_to_degree(value[1], model)), si_to_dxl=lambda value, model: (conv.degree_to_dxl(value[0], model), conv.degree_to_dxl(value[1], model))) _add_control('drive mode', address=0x0A, length=1, access=_DxlAccess.readwrite, models=('MX-106', ), dxl_to_si=conv.dxl_to_drive_mode, si_to_dxl=conv.drive_mode_to_dxl) _add_control('highest temperature limit', address=0x0B, length=1, dxl_to_si=conv.dxl_to_temperature, si_to_dxl=conv.temperature_to_dxl) _add_control('voltage limit', address=0x0C, length=1, nb_elem=2, dxl_to_si=lambda value, model: (conv.dxl_to_voltage(value[0], model), conv.dxl_to_voltage(value[1], model)), si_to_dxl=lambda value, model: (conv.voltage_to_dxl(value[0], model), conv.voltage_to_dxl(value[1], model))) _add_control('max torque', address=0x0E, dxl_to_si=conv.dxl_to_torque, si_to_dxl=conv.torque_to_dxl) _add_control('status return level', address=0x10, length=1, dxl_to_si=conv.dxl_to_status, si_to_dxl=conv.status_to_dxl) _add_control('alarm LED', address=0x11, length=1, dxl_to_si=conv.dxl_to_alarm, si_to_dxl=conv.alarm_to_dxl) _add_control('alarm shutdown', address=0x12, length=1, dxl_to_si=conv.dxl_to_alarm, si_to_dxl=conv.alarm_to_dxl) _add_control('torque_enable', address=0x18, length=1, dxl_to_si=conv.dxl_to_bool, si_to_dxl=conv.bool_to_dxl, getter_name='is_torque_enabled', setter_name='_set_torque_enable') _add_control('LED', address=0x19, length=1, dxl_to_si=conv.dxl_to_bool, si_to_dxl=conv.bool_to_dxl, setter_name='_set_LED', getter_name='is_led_on') _add_control('pid gain', address=0x1A, length=1, nb_elem=3, models=('MX-12', 'MX-28', 'MX-64', 'MX-106'), dxl_to_si=conv.dxl_to_pid, si_to_dxl=conv.pid_to_dxl) _add_control('compliance margin', address=0x1A, length=1, nb_elem=2, models=('AX-12', 'AX-18', 'RX-24', 'RX-28', 'RX-64')) _add_control('compliance slope', address=0x1C, length=1, nb_elem=2, models=('AX-12', 'AX-18', 'RX-24', 'RX-28', 'RX-64')) _add_control('goal position', address=0x1E, dxl_to_si=conv.dxl_to_degree, si_to_dxl=conv.degree_to_dxl) _add_control('moving speed', address=0x20, dxl_to_si=conv.dxl_to_speed, si_to_dxl=conv.speed_to_dxl) _add_control('torque limit', address=0x22, dxl_to_si=conv.dxl_to_torque, si_to_dxl=conv.torque_to_dxl) _add_control('goal position speed load', address=0x1E, nb_elem=3, dxl_to_si=lambda value, model: (conv.dxl_to_degree(value[0], model), conv.dxl_to_speed(value[1], model), conv.dxl_to_load(value[2], model)), si_to_dxl=lambda value, model: (conv.degree_to_dxl(value[0], model), conv.speed_to_dxl(value[1], model), conv.torque_to_dxl(value[2], model))) _add_control('present position', address=0x24, access=_DxlAccess.readonly, dxl_to_si=conv.dxl_to_degree) _add_control('present speed', address=0x26, access=_DxlAccess.readonly, dxl_to_si=conv.dxl_to_speed) _add_control('present load', address=0x28, access=_DxlAccess.readonly, dxl_to_si=conv.dxl_to_load) _add_control('present position speed load', address=0x24, nb_elem=3, access=_DxlAccess.readonly, dxl_to_si=lambda value, model: (conv.dxl_to_degree(value[0], model), conv.dxl_to_speed(value[1], model), conv.dxl_to_load(value[2], model))) _add_control('present voltage', address=0x2A, length=1, access=_DxlAccess.readonly, dxl_to_si=conv.dxl_to_voltage) _add_control('present temperature', address=0x2B, length=1, access=_DxlAccess.readonly, dxl_to_si=conv.dxl_to_temperature) _add_control('moving', address=0x2E, length=1, access=_DxlAccess.readonly, dxl_to_si=conv.dxl_to_bool, getter_name='is_moving') _add_control('punch', address=0x30, length=2, models=('AX-12', 'AX-18', 'RX-24', 'RX-28', 'RX-64')) _add_control('present current', address=0x44, access=_DxlAccess.readonly, models=('MX-64', 'MX-106', 'SR-RH4D',), dxl_to_si=conv.dxl_to_current) _add_control('force control enable', address=0x46, length=1, models=('SR-RH4D',), dxl_to_si=conv.dxl_to_bool, si_to_dxl=conv.bool_to_dxl) _add_control('goal force', address=0x47, models=('SR-RH4D',)) _add_control('goal acceleration', address=0x49, length=1, models=('MX-12, MX-28', 'MX-64', 'MX-106'), dxl_to_si=conv.dxl_to_acceleration, si_to_dxl=conv.acceleration_to_dxl)