跳转至

🤚Inspire dexterous hands

Adam可搭载 Inspire Robotics 的仿人五指灵巧手,该灵巧手具有6个自由度和12个运动关节,可以模拟人手实现复杂动作.

🕹️控制方式

灵巧手官方默认使用串口/485通讯方式进行控制,Adam将为使用透传模块转换为以太网协议,使其作为adam的一个节点子设备方便得进行tpc/udp等以太网操作,更好的融入adam机器人生态.

  • 通讯流程:udp/tcp <-> 串口 <-> 485 <-> hand

下面控制例程使用udp的方式进行五指控制.

id 0 1 2 3 4 5
Joint pinky ring middle index thumb-bend thumb-rotation

上面id对应每个手指的控制,对应下面demo中 write6 函数数值输入顺序

🐍Python demo

import serial
import time
import socket

# hand addr and port
global addr, port
addr = '10.10.10.180'
port = 2333

regdict = {
    'ID': 1000,
    'baudrate': 1001,
    'clearErr': 1004,
    'forceClb': 1009,
    'angleSet': 1486,
    'forceSet': 1498,
    'speedSet': 1522,
    'angleAct': 1546,
    'forceAct': 1582,
    'errCode': 1606,
    'statusCode': 1612,
    'temp': 1618,
    'actionSeq': 2320,
    'actionRun': 2322
}

def writeRegister(ser, id, add, num, val):
    global addr, port
    sbytes = [0xEB, 0x90]
    sbytes.append(id) # device id
    sbytes.append(num + 3) # data len 
    sbytes.append(0x12) # cmd
    sbytes.append(add & 0xFF)
    sbytes.append((add >> 8) & 0xFF) # addr
    for i in range(num):
        sbytes.append(val[i])
    # checksum
    checksum = 0x00
    for i in range(2, len(sbytes)):
        checksum += sbytes[i]
    checksum &= 0xFF
    sbytes.append(checksum)
    # send data
    ser.sendto(bytes(sbytes), (addr, port))
    time.sleep(0.01)
    # recv data
    recv = ser.recv(1024)
    print(recv)

def readRegister(ser, id, add, num, mute=False):
    sbytes = [0xEB, 0x90]
    sbytes.append(id) # device ID
    sbytes.append(0x04) # data len
    sbytes.append(0x11) # cmd
    sbytes.append(add & 0xFF)
    sbytes.append((add >> 8) & 0xFF) # addr
    sbytes.append(num)
    # checksum
    checksum = 0x00
    for i in range(2, len(sbytes)):
        checksum += sbytes[i]
    checksum &= 0xFF
    sbytes.append(checksum)
    # send data
    ser.sendto(bytes(sbytes), (addr, port))
    time.sleep(0.01)
    # recv data
    recv = ser.recv(1024)
    if len(recv) == 0:
        return []
    num = (recv[3] & 0xFF) - 3
    val = []
    for i in range(num):
        val.append(recv[7 + i])
    if not mute:
        print('read:', end='')
        for i in range(num):
            print(val[i], end=' ')
        print()
    return val

def write6(ser, id, str, val):
    if str == 'angleSet' or str == 'forceSet' or str == 'speedSet':
        val_reg = []
        for i in range(6):
            val_reg.append(val[i] & 0xFF)
            val_reg.append((val[i] >> 8) & 0xFF)
        writeRegister(ser, id, regdict[str], 12, val_reg)
    else:
        print('fun error,Correct way:str set to \'angleSet\'/\'forceSet\'/\'speedSet\',val is a list of length 6, with values ranging from 0 to 1000. -1 is allowed as a placeholder.')

def read6(ser, id, str):
    if str == 'angleSet' or str == 'forceSet' or str == 'speedSet' or str == 'angleAct' or str == 'forceAct':
        val = readRegister(ser, id, regdict[str], 12, True)
        if len(val) < 12:
            print('no data')
            return
        val_act = []
        for i in range(6):
            val_act.append((val[2*i] & 0xFF) + (val[1 + 2*i] << 8))
        print('read:', end='')
        for i in range(6):
            print(val_act[i], end=' ')
        print()
    elif str == 'errCode' or str == 'statusCode' or str == 'temp':
        val_act = readRegister(ser, id, regdict[str], 6, True)
        if len(val_act) < 6:
            print('not recv data')
            return
        print('read:', end='')
        for i in range(6):
            print(val_act[i], end=' ')
        print()
    else:
        print('fun error,Correct way:str set to \'angleSet\'/\'forceSet\'/\'speedSet\'/\'angleAct\'/\'forceAct\'/\'errCode\'/\'statusCode\'/\'temp\'')

if __name__ == '__main__':

    ser = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    ser.settimeout(1)

    print('Set dexterous hand motion angle parameters,--1 means not to set the motion angle!')
    write6(ser, 1, 'speedSet', [100, 100, 100, 100, 100, 100])
    time.sleep(2)

    print('Set dexterity hand grip strength parameters!')
    write6(ser, 1, 'forceSet', [500, 500, 500, 500, 500, 500])
    time.sleep(1)

    print('Set dexterous hand motion angle parameters0,-1 means not to set the motion angle!')
    write6(ser, 1, 'angleSet', [0, 0, 0, 0, 400, -1])
    time.sleep(3)

    # Read the actual angle
    read6(ser, 1, 'angleAct')
    time.sleep(1)

    print('Set dexterous hand motion angle parameters: 1000,-1 means not to set the motion angle!')
    write6(ser, 1, 'angleSet', [1000, 1000, 1000, 1000, 400, -1])
    time.sleep(3)

    # Read the actual angle
    read6(ser, 1, 'angleAct')
    time.sleep(1)

    # Read error code
    read6(ser, 1, 'errCode')
    time.sleep(1)

    print('Set up a dexterity library sequence:8!')
    writeRegister(ser, 1, regdict['actionSeq'], 1, [8])
    time.sleep(1)

    print('Run the current sequence of dexterous hand actions!')
    writeRegister(ser, 1, regdict['actionRun'], 1, [1])