DoF - a Robotiq Community
Warning sign
The Dof Community was shut down in June 2023. This is a read-only archive.
If you have questions about Robotiq products please reach our support team.
NaN

Hello,
I am able to open and close the 2F-85 gripper I have, which is mounted on an UR5, but am struggling to figure out how to read the gripper position.

Originally I had the USB-serial converter directly plugged into my computer and reading the gripper position (over /dev/ttyUSB0) was really easy (I used python, as per https://blog.robotiq.com/controlling-the-robotiq-2f-gripper-with-modbus-commands-in-python). However, then I could not coordinate the gripper with my UR5's movements.

Therefore I plugged the converter to the USB port within the UR5 control box, so that I can command the gripper in sync with the robot `movel` commands. I am able to open and close it using the library https://github.com/jkur/python-urx/blob/SW3.5/urx/robotiq_two_finger_gripper.py, or roughly:

        header = "def myProg():\n"
        prog = header
        prog += 'socket_open(\"{}\",{},\"{}\"\n)'.format("127.0.0.1",
                                                         63352,
                                                         "gripper_socket")
        prog += "socket_set_var(\"{}\",{},\"{}\")\n".format("ACT", 1,
                                                            "gripper_socket")
        prog += "socket_set_var(\"{}\",{},\"{}\")\n".format("GTO", 1,
                                                            "gripper_socket")

        if str(command) == 'open':
                msg = "socket_set_var(\"{}\",{},\"{}\")\n".format("POS", 0,
                                                                  "gripper_socket")
        else:
                msg = "socket_set_var(\"{}\",{},\"{}\")\n".format("POS", 1,
                                                                  "gripper_socket")
                prog += msg
        prog +=
"end\n"

self.send_program(prog)


However, the python-urx library leaves "getting the gripper status" as an exercise for the reader, and for the life of me I cannot figure out how to do it. I thought it would be so easy, since when I had it plugged into the laptop it was very straightforward. But now, I'm unclear how to read the data.

The library includes code to get the robot status (e.g. joint configuration, tool position), but as far as I can tell the robotiq gripper status is not included in that information.

Does anyone have python code for reading the gripper status over the UR5 tcp/ip protocol, or be able to give an example of how to do so?

Thank you!







NaN

For reference, the parser is at https://github.com/jkur/python-urx/blob/SW3.5/urx/ursecmon.py#L48.
And the data I can get via `self.get_all_data()` is:

{'robot state: ': {'AdditionalInfo': {'teachButtonPressed': False
, 'teachButtonEnabled': True
, 'type': 8
, 'size': 9
}
, 'MasterBoardData': {'analogInputRange0': 1
, 'analogInputRange1': 1
, 'analogOutput0': 0.004000000189989805
, 'analogOutput1': 0.004000000189989805
, 'digitalOutputBits': 0
, 'robotVoltage48V': 48.13019943237305
, 'digitalInputBits': 0
, 'analogInput0': 0.0040280818939208984
, 'analogInput1': 0.0040280818939208984
, 'robotCurrent': 0.7877604365348816
, 'masterIOCurrent': 0.07211295515298843
, 'analogInputDomain0': 0
, 'analogInputDomain1': 0
, 'type': 3
, 'masterBoardTemperature': 27.6484375
, 'size': 75
}
, 'SecondaryClientData': {'type': 16
, 'size': 682
}
, 'ForceModeData': {'rx': 0.0
, 'ry': 0.0
, 'rz': 0.0
, 'y': 0.0
, 'x': 0.0
, 'z': 0.0
, 'type': 7
, 'robotDexterity': 0.0017944129077513415
, 'size': 61
}
, 'ToolData': {'toolOutputVoltage': 0
, 'analoginputRange2': 1
, 'analoginputRange3': 1
, 'toolVoltage48V': 461.459228515625
, 'toolMode': 253
, 'toolCurrent': 0.0
, 'toolTemperature': 43.0
, 'analogInput2': 0.06692492961883545
, 'analogInput3': 0.06536853313446045
, 'type': 2
, 'size': 37
}
, 'CartesianInfo': {'tcpOffsetY': 0.0
, 'tcpOffsetRy': 0.0
, 'tcpOffsetZ': 0.0
, 'tcpOffsetRz': 0.0
, 'Rx': 2.10488813323439
, 'Ry': -2.2127665018592837
, 'Rz': -0.017383455219535784
, 'tcpOffsetRx': 0.0
, 'Y': -0.0003367998686304354
, 'X': 0.3490712299453407
, 'Z': 0.24887897745368975
, 'type': 4
, 'tcpOffsetX': 0.0
, 'size': 101
}
, 'RobotModeData': {'isSecurityStopped': False
, 'speedScaling': 0.0
, 'isProgramPaused': False
, 'timestamp': 1339528000
, 'isRealRobotEnabled': True
, 'speedFractionLimit': 63
, 'robotMode': 7
, 'isProgramRunning': False
, 'isPowerOnRobot': True
, 'isPhysicalRobotConnected': True
, 'isEmergencyStopped': False
, 'speedFraction': 1.0
, 'type': 0
, 'controlMode': 0
, 'size': 47
}
, 'JointData': {'jointMode5': 253
, 'qd_actual4': 0.0
, 'jointMode4': 253
, 'T_motor0': 27.549991607666016
, 'T_motor5': 33.909576416015625
, 'size': 251
, 'V_actual4': 48.07600021362305
, 'q_target4': -1.605703
, 'qd_actual5': 0.015435682609677315
, 'V_actual0': 47.81800079345703
, 'V_actual1': 47.803001403808594
, 'V_actual2': 47.696998596191406
, 'V_actual3': 47.71200180053711
, 'q_actual3': -1.954794708882467
, 'q_actual2': 2.2794532775878906
, 'q_actual1': -1.8465498129474085
, 'q_actual0': -3.447080198918478
, 'T_motor4': 32.6035041809082
, 'q_actual5': -0.26228505769838506
, 'q_actual4': -1.605781380330221
, 'I_actual3': -0.2363813817501068
, 'I_actual2': -1.3361190557479858
, 'I_actual1': -1.0469255447387695
, 'I_actual0': -0.3183371126651764
, 'q_target0': -3.447025
, 'q_target1': -1.846558
, 'q_target2': 2.2794
, 'T_motor1': 26.4632511138916
, 'T_motor2': 27.639751434326172
, 'type': 1
, 'T_motor3': 31.349990844726562
, 'qd_actual2': -0.0
, 'qd_actual3': 0.0
, 'qd_actual0': 0.0
, 'qd_actual1': 0.0
, 'jointMode1': 253
, 'jointMode0': 253
, 'jointMode3': 253
, 'jointMode2': 253
, 'q_target3': -1.9547689999999998
, 'I_actual5': 0.16470444202423096
, 'V_actual5': 47.87900161743164
, 'q_target5': -0.2617989999999999
, 'I_actual4': -0.05490148067474365
, 'T_micro5': 33.551246643066406
, 'T_micro4': 35.86604309082031
, 'T_micro3': 32.943389892578125
, 'T_micro2': 30.52123260498047
, 'T_micro1': 31.656269073486328
, 'T_micro0': 30.62255859375
}
}
, '\n'
}

However, none of this appears to correlate to the gripper position.
I'm wondering if perhaps I could issue
rq_current_pos()
textmsg(rq_pos)

and hope the textmsg will be picked up by get_all_data somehow? I really thought this would be straightforward...

NaN

I've gotten the hack of using the analogOutput on the UR to report the gripper position to work. So, in URSCRIPT I have
def myProg():
    socket_close("gripper_socket")
    socket_open("127.0.0.1",63352,"gripper_socket")
    set_analog_inputrange(0,0)
    set_analog_inputrange(1,0)
    set_analog_inputrange(2,0)
    set_analog_inputrange(3,0)
    set_analog_outputdomain(0,1)
    set_analog_outputdomain(1,1)
    set_tool_voltage(0)
    set_runstate_outputs([])
    set_payload(0.85)
    socket_set_var("SPE",255,"gripper_socket")
    sync()
    socket_set_var("FOR",50,"gripper_socket")
    sync()
    sleep(0.1)
    socket_set_var("POS",255,"gripper_socket")
    sync()
    sleep(0.1)

def analogToPos():
    socket_close("gripper_socket")
    socket_open("127.0.0.1", 63352, "gripper_socket")
    rq_pos = socket_get_var("POS","gripper_socket")
    sync()
    set_standard_analog_out(0, rq_pos / 255)
    textmsg(rq_pos)
end

Of course, this is actually streamed out on my end over python. For instance, using the python-urx library linked above,

edit urx/urrobot.py

    def set_analog_out_to_pos(self):
        prog = "def analogToPos():\n"
        prog += '\tsocket_close("gripper_socket")\n'
        prog += '\tsocket_open("127.0.0.1", 63352, "gripper_socket")\n'
        prog += '\trq_pos = socket_get_var("POS","gripper_socket")\n'
        prog += '\tsync()\n'
        prog += "\tset_standard_analog_out(0, rq_pos / 255)\n"
        prog += "\ttextmsg(rq_pos)\n"
        prog += "end"
        self.send_program(prog)

After calling the above, I can use the python-urx library to read the analog port.
  data = rob.secmon.get_all_data(wait=False)
          print("analog state: ", data['MasterBoardData']['analogOutput0'], '\n')


===

As a documentation of the trouble shooting process:

I downloaded the robotiq urcap (as per the "software" page) and used the ur pendant write short programs.
I saved that program to a usb, and opened it in a text editor on my computer. There I found the functions (as described in the robotiq user manual pdf). For instance there is the function --
  def rq_current_pos(gripper_socket="1"):
      enter_critical
      rq_pos = socket_get_var("POS",gripper_socket)
      exit_critical
      sync()
      return rq_pos
  end

I also used liberally, textmsg() to write values to the pendant's log. This helped debug e.g. rq_current_pos_norm outputs between [0,100] and rq_pos as defined above outputs [0,255], whereas the set_standard_analog_out desires a value between [0,1]. On the other hand, when I am reading the analog output over the so-called "ur5 matlab interface / secondary monitor / port 3002", I will get a value between [0,10].

zoom
I can also use the pendant to both view in the I/O tab, the "Analog Output', as well as drag the slider to make sure my state reader is behaving.
Finally, I realized that I need to wait a little longer (~1 sec) to read the analogoutput, since I'm not waiting until the gripper has stopped moving (for now) to proceed.
For instance,

        robotiqgrip.gripper_action(0) # open
        time.sleep(1)
        rob.set_analog_out_to_pos()
        time.sleep(0.5)
        data = rob.secmon.get_all_data(wait=False)
        print("\n  !----- analog state open: ", data['MasterBoardData']['analogOutput0'], '\n')
        time.sleep(1)

        robotiqgrip.gripper_action(255)
        time.sleep(1)
        rob.set_analog_out_to_pos()
        time.sleep(0.5)
        # pose = rob.getl()
        data = rob.secmon.get_all_data(wait=False)
        print("\n !-----  analog state close: ", data['MasterBoardData']['analogOutput0'], '\n')
        time.sleep(1)

('\n !-----  analog state close: ', 7.490196228027344, '\n')
('\n  !----- analog state open: ', 0.11764705926179886, '\n')


Now I can set my own threshold for whether an object has been picked up. Maybe in the future I will investigate the rest of the robotiq urcap functions, e.g. for object detection.

Hurray!