Source code for pypot.dynamixel

import sys
import platform
import glob
import logging

import serial.tools.list_ports


from .io import DxlIO, Dxl320IO
from .error import BaseErrorHandler
from .syncloop import BaseDxlController
from .motor import DxlMXMotor, DxlAXRXMotor, DxlXL320Motor, DxlSRMotor
from .io.abstract_io import DxlError

from ..robot import Robot

logger = logging.getLogger(__name__)


def _get_available_ports():
    """ Tries to find the available serial ports on your system. """
    if platform.system() == 'Darwin':
        return glob.glob('/dev/tty.usb*')

    elif platform.system() == 'Linux':
        return glob.glob('/dev/ttyACM*') + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyAMA*')

    elif sys.platform.lower() == 'cygwin':
        return glob.glob('/dev/com*')

    elif platform.system() == 'Windows':
        import _winreg
        import itertools

        ports = []
        path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
        key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, path)

        for i in itertools.count():
            try:
                ports.append(str(_winreg.EnumValue(key, i)[1]))
            except WindowsError:
                return ports
    else:
        raise EnvironmentError('{} is an unsupported platform, cannot find serial ports !'.format(platform.system()))
    return []


[docs]def get_available_ports(only_free=False): ports = _get_available_ports() if only_free: ports = list(set(ports) - set(DxlIO.get_used_ports())) return ports
def get_port_vendor_info(port=None): """ Return vendor informations of a usb2serial device. It may depends on the Operating System. :param string port: port of the usb2serial device :Example: Result with a USB2Dynamixel on Linux: In [1]: import pypot.dynamixel In [2]: pypot.dynamixel.get_port_vendor_info('/dev/ttyUSB0') Out[2]: 'USB VID:PID=0403:6001 SNR=A7005LKE' """ port_info_dict = dict((x[0], x[2]) for x in serial.tools.list_ports.comports()) return port_info_dict[port] if port is not None else port_info_dict
[docs]def find_port(ids, strict=True): """ Find the port with the specified attached motor ids. :param list ids: list of motor ids to find :param bool strict: specify if all ids should be find (when set to False, only half motor must be found) .. warning:: If two (or more) ports are attached to the same list of motor ids the first match will be returned. """ ids_founds = [] for port in get_available_ports(): for DxlIOCls in (DxlIO, Dxl320IO): try: with DxlIOCls(port) as dxl: _ids_founds = dxl.scan(ids) ids_founds += _ids_founds if strict and len(_ids_founds) == len(ids): return port if not strict and len(_ids_founds) >= len(ids) / 2: logger.warning('Missing ids: {}'.format(ids, list(set(ids) - set(_ids_founds)))) return port if len(ids_founds) > 0: logger.warning('Port:{} ids found:{}'.format(port, _ids_founds)) except DxlError: logger.warning('DxlError on port {}'.format(port)) continue raise IndexError('No suitable port found for ids {}. These ids are missing {} !'.format( ids, list(set(ids) - set(ids_founds))))
[docs]def autodetect_robot(): """ Creates a :class:`~pypot.robot.robot.Robot` by detecting dynamixel motors on all available ports. """ motor_controllers = [] for port in get_available_ports(): for DxlIOCls in (DxlIO, Dxl320IO): dxl_io = DxlIOCls(port) ids = dxl_io.scan() if not ids: dxl_io.close() continue models = dxl_io.get_model(ids) motorcls = { 'MX': DxlMXMotor, 'RX': DxlAXRXMotor, 'AX': DxlAXRXMotor, 'XL': DxlXL320Motor, 'SR': DxlSRMotor, } motors = [motorcls[model[:2]](id, model=model) for id, model in zip(ids, models)] c = BaseDxlController(dxl_io, motors) motor_controllers.append(c) break return Robot(motor_controllers)