├── xml_rpc_on_robot
├── xml_request_list_methods.xml
├── xml_request_rg_calibration.xml
├── xml_request_get_rg_width.xml
├── xml_request_sys_method_help.xml
├── xml_request_vg10_get_vacuum.xml
├── twofg
│ ├── xml_request_get_twofg_status.xml
│ ├── xml_request_get_twofg_width.xml
│ ├── xml_request_get_all_twofg_variables.xml
│ ├── xml_request_twofg_grip.xml
│ └── get_all_twofg_variables_response.xml
├── xml_request_get_all_rg_variables.xml
├── xml_request_add.xml
├── xml_request_grip.xml
├── xml_request_vg10_grip.xml
├── xml_request_vg10_release.xml
├── README.md
├── get_all_rg_variables_response.xml
├── to_do_list.txt
├── .vscode
│ └── settings.json
├── test.py
└── list_methods_response.xml
├── onRobot
├── onRobot
│ ├── __init_.py
│ └── gripper.py
└── setup.py
├── .gitignore
├── LICENSE
├── README.md
└── UOY-logo.svg
/xml_rpc_on_robot/xml_request_list_methods.xml:
--------------------------------------------------------------------------------
1 |
2 | system.listMethods
3 |
4 |
--------------------------------------------------------------------------------
/onRobot/onRobot/__init_.py:
--------------------------------------------------------------------------------
1 | """
2 | onRobot
3 |
4 | An onRobot python library.
5 | """
6 |
7 | __version__ = "0.1.0"
8 | __author__ = 'Ryan McKenna'
9 | __credits__ = 'The University of York'
10 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_rg_calibration.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | rg_calibration
4 |
5 |
6 | 1.1
7 |
8 |
9 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_get_rg_width.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | rg_get_width
4 |
5 |
6 | 0
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_sys_method_help.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | system.methodSignature
4 |
5 |
6 | vg10_release
7 |
8 |
9 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_vg10_get_vacuum.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | vg10_get_vacuum
4 |
5 |
6 | 0
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/twofg/xml_request_get_twofg_status.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | twofg_get_status
4 |
5 |
6 | 0
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/twofg/xml_request_get_twofg_width.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | twofg_get_max_force
4 |
5 |
6 | 0
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_get_all_rg_variables.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | rg_get_all_variables
4 |
5 |
6 | 0
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/twofg/xml_request_get_all_twofg_variables.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | twofg_get_all_variables
4 |
5 |
6 | 0
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | add
4 |
5 |
6 | 111
7 |
8 |
9 | 222
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | onRobot/dist/onRobot-0.1.0-py2.py3-none-any.whl
2 | onRobot/dist/onRobot-0.1.0.tar.gz
3 | onRobot/onRobot.egg-info/dependency_links.txt
4 | onRobot/onRobot.egg-info/PKG-INFO
5 | onRobot/onRobot.egg-info/SOURCES.txt
6 | onRobot/onRobot.egg-info/top_level.txt
7 | onRobot/build/lib/onRobot/gripper.py
8 | onRobot/build/lib/onRobot/__init_.py
9 | onRobot/dist/onRobot-0.1.0-py3-none-any.whl
10 | onRobot/onRobot/__pycache__/gripper.cpython-38.pyc
11 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_grip.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | rg_grip
4 |
5 |
6 | 0
7 |
8 |
9 | 30.0
10 |
11 |
12 | 0.6
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_vg10_grip.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | vg10_grip
4 |
5 |
6 | 0
7 |
8 |
9 | 2
10 |
11 |
12 | 10.0
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/twofg/xml_request_twofg_grip.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | twofg_grip_external
4 |
5 |
6 | 0
7 |
8 |
9 | 30.0
10 |
11 |
12 | 0.6
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/xml_request_vg10_release.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | vg10_release
4 |
5 |
6 | 0
7 |
8 |
9 | 1
10 |
11 |
12 | 1
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/README.md:
--------------------------------------------------------------------------------
1 | # All rg2 function names, implement each one in python or c++
2 |
3 | rg_stop
4 | rg_grip
5 | rg_calibration
6 | rg_get_all_variables
7 | rg_get_all_double_variables
8 | rg_get_all_integer_variable>
9 | rg_get_all_boolean_variable>
10 | rg_get_speed
11 | rg_get_depth
12 | rg_get_relative_depth
13 | rg_get_angle
14 | rg_get_angle_speed
15 | rg_get_width
16 | rg_get_fingertip_offset
17 | rg_get_status
18 | rg_get_busy
19 | rg_get_grip_detected
20 | rg_get_s1_pushed
21 | rg_get_s1_triggered
22 | rg_get_s2_pushed
23 | rg_get_s2_triggered
24 | rg_get_safety_failed
25 | rg_set_fingertip_offset
--------------------------------------------------------------------------------
/onRobot/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup(
4 | name='onRobot',
5 | version='0.1.0',
6 | description='A simple gripper library for UR robot with onRobot gripper, no onrobot compute box needed!',
7 | url='https://github.com/RyanPaulMcKenna/onRobot',
8 | author='Ryan McKenna',
9 | author_email='ryan.mckenna@york.ac.uk',
10 | license='MIT',
11 | packages=['onRobot'],
12 | install_requires=[],
13 | classifiers=[
14 | 'Development Status :: 1 - Planning',
15 | 'Intended Audience :: Science/Research',
16 | 'License :: OSI Approved :: BSD License',
17 | 'Operating System :: POSIX :: Linux',
18 | 'Programming Language :: Python :: 2.7',
19 | 'Programming Language :: Python :: 3',
20 | ],
21 | )
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 The University of York, Ryan McKenna
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/get_all_rg_variables_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | angle
6 | 126.8000030517578
7 | angle_speed
8 | 2395.10009765625
9 | busy
10 | 0
11 | depth
12 | 38.5
13 | fingertip_offset
14 | 4.599999904632568
15 | relative_depth
16 | 2.5
17 | s1_pushed
18 | 0
19 | s1_triggered
20 | 0
21 | s2_pushed
22 | 0
23 | s2_triggered
24 | 0
25 | safety_failed
26 | 0
27 | speed
28 | 0
29 | status
30 | 0
31 | width
32 | 100.8000030517578
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/twofg/get_all_twofg_variables_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | busy
6 | 0
7 | error_linear_sensor
8 | 0
9 | error_not_calibrated
10 | 0
11 | external_width
12 | 70.3000030517578
13 | finger_height
14 | 45
15 | finger_length
16 | 8.5
17 | finger_orientation_outward
18 | 1
19 | fingertip_offset
20 | 3.5
21 | force
22 | 2
23 | grip_detected
24 | 0
25 | internal_width
26 | 84.3000030517578
27 | max_external_width
28 | 71
29 | max_force
30 | 140
31 | max_internal_width
32 | 85
33 | min_external_width
34 | 33
35 | min_internal_width
36 | 47
37 | status
38 | 0
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/to_do_list.txt:
--------------------------------------------------------------------------------
1 | # To do list
2 |
3 | Now I can control robot through ext ctrl and move with ros controllers.
4 |
5 | I can also move the onRobot gripper, however I want to without it interferring with ros
6 | or the ext control program in anyway.
7 |
8 | I need to put all this behaviour in a fully abstracted ros node.
9 |
10 | This method is purely using http requests to send xml files to the xmlrpc server.
11 |
12 | So I wil need to save most recent values of gripper set to keep them up to date
13 | for my whole ros program.
14 |
15 | 1. change robot description to the one that has the onRobot rg2 gripper.
16 | do this in the the standard launch command and in rviz, you can now also use move it
17 | if neccessary.
18 | 2. You will to write some classes and files that abstract this networking and interface with ros
19 | neatly as a package would. Keep track of gripper variables and use them to update rviz.
20 | rviz likely just subscribes to some topic that makes them available you just need to
21 | make a publisher and link it up.
22 |
23 | Here are the commands I used to work it out:
24 | curl -X POST -d @xml_request_add.xml 192.168.0.99:41414
25 | curl -X POST -d @xml_request_add.xml 192.168.0.99:31416
26 |
27 | If use extra sensors I can wire them into the power and analog inputs on the control box.
28 |
29 | Somehow need to read from these analog inputs passively in a way that doesn't interfere with
30 | ros or the http requests for the gripper.
31 |
32 | Maybe I can set up on robot fieldbus or modbus that or a just a socat device that can read from those
33 | analog inputs and set the values in registers that I can access by modbus client on my machine
34 |
35 |
36 |
37 |
38 | All the info about move it and rviz is here
39 | https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/doc/usage_example.md
40 |
41 |
42 | Here is the urdf
43 | https://github.com/AndrejOrsula/ur5_rg2_ign
--------------------------------------------------------------------------------
/xml_rpc_on_robot/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "ostream": "cpp",
4 | "cctype": "cpp",
5 | "clocale": "cpp",
6 | "cmath": "cpp",
7 | "cstdarg": "cpp",
8 | "cstddef": "cpp",
9 | "cstdio": "cpp",
10 | "cstdlib": "cpp",
11 | "cstring": "cpp",
12 | "ctime": "cpp",
13 | "cwchar": "cpp",
14 | "cwctype": "cpp",
15 | "array": "cpp",
16 | "atomic": "cpp",
17 | "hash_map": "cpp",
18 | "hash_set": "cpp",
19 | "strstream": "cpp",
20 | "*.tcc": "cpp",
21 | "bitset": "cpp",
22 | "chrono": "cpp",
23 | "codecvt": "cpp",
24 | "complex": "cpp",
25 | "condition_variable": "cpp",
26 | "cstdint": "cpp",
27 | "deque": "cpp",
28 | "list": "cpp",
29 | "unordered_map": "cpp",
30 | "unordered_set": "cpp",
31 | "vector": "cpp",
32 | "exception": "cpp",
33 | "algorithm": "cpp",
34 | "filesystem": "cpp",
35 | "functional": "cpp",
36 | "iterator": "cpp",
37 | "map": "cpp",
38 | "memory": "cpp",
39 | "memory_resource": "cpp",
40 | "numeric": "cpp",
41 | "optional": "cpp",
42 | "random": "cpp",
43 | "ratio": "cpp",
44 | "set": "cpp",
45 | "string": "cpp",
46 | "string_view": "cpp",
47 | "system_error": "cpp",
48 | "tuple": "cpp",
49 | "type_traits": "cpp",
50 | "utility": "cpp",
51 | "fstream": "cpp",
52 | "future": "cpp",
53 | "initializer_list": "cpp",
54 | "iomanip": "cpp",
55 | "iosfwd": "cpp",
56 | "iostream": "cpp",
57 | "istream": "cpp",
58 | "limits": "cpp",
59 | "mutex": "cpp",
60 | "new": "cpp",
61 | "sstream": "cpp",
62 | "stdexcept": "cpp",
63 | "streambuf": "cpp",
64 | "thread": "cpp",
65 | "cfenv": "cpp",
66 | "cinttypes": "cpp",
67 | "typeindex": "cpp",
68 | "typeinfo": "cpp",
69 | "variant": "cpp",
70 | "bit": "cpp"
71 | }
72 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # onRobot
2 |
3 | A simple gripper library to use a Universal Robot with an onRobot gripper, no onrobot compute box needed.
4 | Please note you must install the URcap file on the UR teach pendant.
5 | You must also have set all the correct IP addresses in the networking settings of the UR Teach Pendant and the computer you are connecting to the Robot via the ethernet.
6 |
7 |
8 | # Supported onRobot Grippers
9 | - [x] RG2
10 | - [x] VG10
11 | - [x] 2FG7
12 | - [ ] Gecko
13 | - [ ] SG
14 | - [ ] TFG
15 | - [ ] SDR
16 | - [ ] 2FG
17 | - [ ] MG
18 | - [ ] FGP
19 |
20 | **See further down for usage examples**
21 |
22 | - Simple and easy to use!
23 | - No onRobot compute box needed!
24 | - Communicates with XML-RPC interface so is compatible with ROS driver!
25 | - Contributions welcome!
26 | - onRobot URcap must be installed on Universal Robots Teach Pendant.
27 |
28 | # Install instructions
29 |
30 | ```bash
31 |
32 | pip install onrobot
33 |
34 |
35 | ```
36 | # Example Usage
37 |
38 | ```python
39 | import onRobot.gripper as gripper
40 |
41 | rg_id = 0
42 | ip = "192.168.56.101"
43 | rg_gripper = gripper.RG2(ip,rg_id)
44 |
45 | rg_width = rg_gripper.get_rg_width()
46 | print("rg_width: ",rg_width)
47 |
48 | target_force = 40.00
49 |
50 | rg_gripper.rg_grip(100.0, target_force)
51 |
52 |
53 |
54 | ```
55 |
56 |
57 | # Functions implemented for the RG2
58 |
59 | - [ ] rg_stop
60 | - [x] rg_grip
61 | - [ ] rg_calibration
62 | - [ ] rg_get_all_variables
63 | - [ ] rg_get_all_double_variables
64 | - [ ] rg_get_all_integer_variable>
65 | - [ ] rg_get_all_boolean_variable>
66 | - [ ] rg_get_speed
67 | - [ ] rg_get_depth
68 | - [ ] rg_get_relative_depth
69 | - [ ] rg_get_angle
70 | - [ ] rg_get_angle_speed
71 | - [x] rg_get_width
72 | - [ ] rg_get_fingertip_offset
73 | - [ ] rg_get_status
74 | - [ ] rg_get_busy
75 | - [ ] rg_get_grip_detected
76 | - [ ] rg_get_s1_pushed
77 | - [ ] rg_get_s1_triggered
78 | - [ ] rg_get_s2_pushed
79 | - [ ] rg_get_s2_triggered
80 | - [ ] rg_get_safety_failed
81 | - [ ] rg_set_fingertip_offset
82 |
83 |
84 | # Functions implemented for the VG10
85 | - [x] vg10_grip
86 | - [x] vg10_release
87 | - [] vg10_idle
88 | - [] vg10_get_vacuum
89 | - [] vg10_get_all_double_variables
90 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/test.py:
--------------------------------------------------------------------------------
1 | import pycurl
2 | import xmlrpc.client
3 | from io import BytesIO
4 |
5 |
6 | class OnRobotRG2Gripper:
7 | def __init__(self, rg_id: int = 0) -> None:
8 | self.rg_id = rg_id
9 | self.rg_width = None
10 | self.rg_force = None
11 |
12 | def clear_cache(self) -> None:
13 | self.rg_width = None
14 | self.rg_force = None
15 |
16 | def get_rg_force(self) -> float:
17 | return self.rg_force
18 |
19 | def get_rg_width(self) -> float:
20 | xml_request = f"""
21 |
22 | rg_get_width
23 |
24 |
25 | {self.rg_id}
26 |
27 |
28 | """
29 |
30 | headers = ["Content-Type: application/x-www-form-urlencoded"]
31 |
32 | data = xml_request.replace('\r\n','').encode()
33 |
34 | # Create a new cURL object
35 | curl = pycurl.Curl()
36 |
37 | # Set the URL to fetch
38 | curl.setopt(curl.URL, 'http://192.168.56.101:41414')
39 | curl.setopt(curl.HTTPHEADER, headers)
40 | curl.setopt(curl.POSTFIELDS, data)
41 | # Create a BytesIO object to store the response
42 | buffer = BytesIO()
43 | curl.setopt(curl.WRITEDATA, buffer)
44 |
45 | # Perform the request
46 | curl.perform()
47 |
48 | # Get the response body
49 | response = buffer.getvalue()
50 |
51 | # Print the response
52 | print(response.decode('utf-8'))
53 |
54 | # Close the cURL object
55 | curl.close()
56 |
57 | xml_response = xmlrpc.client.loads(response.decode('utf-8'))
58 | rg_width = float(xml_response[0][0])
59 | #print(rg_width)
60 | return rg_width
61 |
62 |
63 | def rg_grip(self, target_width: float = 100, target_force: float= 10) -> bool:
64 | #assert target_width <= 100 and target_width >= 0, 'Target Width must be within the range [0,100]'
65 | #assert target_force <= 40 or target_force >= 0, 'Target force must be within the range [0,40]'
66 |
67 | # WARNING: params will be sent straight to electrical system with no error checking on robot!
68 | if (target_width > 100):
69 | target_width = 100
70 | if(target_width < 0):
71 | target_width = 0
72 | if(target_force > 40):
73 | target_force = 40
74 | if(target_force < 0):
75 | target_force = 0
76 |
77 | xml_request = f"""
78 |
79 | rg_grip
80 |
81 |
82 | {self.rg_id}
83 |
84 |
85 | {target_width}
86 |
87 |
88 | {target_force}
89 |
90 |
91 | """
92 |
93 | headers = ["Content-Type: application/x-www-form-urlencoded"]
94 |
95 | # headers = ["User-Agent: Python-PycURL", "Accept: application/json"]
96 | data = xml_request.replace('\r\n','').encode()
97 | # Create a new cURL object
98 | curl = pycurl.Curl()
99 |
100 | # Set the URL to fetch
101 | curl.setopt(curl.URL, 'http://192.168.56.101:41414')
102 | curl.setopt(curl.HTTPHEADER, headers)
103 | curl.setopt(curl.POSTFIELDS, data)
104 | # Create a BytesIO object to store the response
105 | buffer = BytesIO()
106 | curl.setopt(curl.WRITEDATA, buffer)
107 |
108 | # Perform the request
109 | curl.perform()
110 |
111 | # Get the response body
112 | response = buffer.getvalue()
113 |
114 | # Print the response
115 | print(response.decode('utf-8'))
116 |
117 | # Close the cURL object
118 | curl.close()
119 |
120 |
121 | print("main")
122 | gripper = OnRobotRG2Gripper()
123 | gripper.rg_grip(0.0,15.0)
124 |
--------------------------------------------------------------------------------
/xml_rpc_on_robot/list_methods_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | system.listMethods
6 | system.methodExist
7 | system.methodHelp
8 | system.methodSignature
9 | system.multicall
10 | system.shutdown
11 | system.capabilities
12 | system.getCapabilities
13 | set_toolconnector_mode
14 | set_toolconnector_simulator
15 | get_discovery
16 | cb_get_stop_devices_when_robot_is_stopped
17 | cb_enable_stop_devices_when_robot_is_stopped
18 | rg_stop
19 | rg_grip
20 | rg_calibration
21 | rg_get_all_variables
22 | rg_get_all_double_variables
23 | rg_get_all_integer_variables
24 | rg_get_all_boolean_variables
25 | rg_get_speed
26 | rg_get_depth
27 | rg_get_relative_depth
28 | rg_get_angle
29 | rg_get_angle_speed
30 | rg_get_width
31 | rg_get_fingertip_offset
32 | rg_get_status
33 | rg_get_busy
34 | rg_get_grip_detected
35 | rg_get_s1_pushed
36 | rg_get_s1_triggered
37 | rg_get_s2_pushed
38 | rg_get_s2_triggered
39 | rg_get_safety_failed
40 | rg_set_fingertip_offset
41 | vg10_grip
42 | vg10_release
43 | vg10_idle
44 | vg10_get_vacuum
45 | vg10_get_all_double_variables
46 | gecko_set_pad_position
47 | gecko_set_preload_spec
48 | gecko_reset_error_logs
49 | gecko_get_all_variables
50 | gecko_get_all_double_variables
51 | gecko_get_all_integer_variables
52 | gecko_get_all_boolean_variables
53 | gecko_get_preload_force
54 | gecko_get_ultrasonic
55 | gecko_get_part_detected
56 | gecko_get_pads_worn
57 | gecko_get_error
58 | gecko_get_pad_position
59 | gecko_get_busy
60 | sg_grip
61 | sg_initialize
62 | sg_stop
63 | sg_home
64 | sg_calibrate
65 | sg_get_all_variables
66 | sg_get_all_double_variables
67 | sg_get_all_integer_variables
68 | sg_get_all_boolean_variables
69 | sg_get_sg_tool_id
70 | sg_get_width
71 | sg_get_depth
72 | sg_get_depth_relative
73 | sg_get_depth_static_silicone
74 | sg_get_min_max
75 | sg_get_max_open
76 | sg_get_min_open
77 | sg_get_status
78 | sg_get_busy
79 | sg_get_initialized
80 | sg_get_grip_detected
81 | sg_get_calibrated
82 | sg_get_error
83 | tfg_move
84 | tfg_grip
85 | tfg_flexible_grip
86 | tfg_set_finger_position
87 | tfg_set_finger_length
88 | tfg_set_fingertip_offset
89 | tfg_set_power_limit
90 | tfg_stop
91 | tfg_get_all_variables
92 | tfg_get_all_double_variables
93 | tfg_get_all_integer_variables
94 | tfg_get_all_boolean_variables
95 | tfg_get_status
96 | tfg_get_busy
97 | tfg_get_grip_detected
98 | tfg_get_force_grip_detected
99 | tfg_get_calibration_valid
100 | tfg_get_safety_dc_error
101 | tfg_get_other_error
102 | tfg_get_diameter_raw
103 | tfg_get_diameter
104 | tfg_get_force
105 | tfg_get_finger_position
106 | tfg_get_finger_length
107 | tfg_get_fingertip_offset
108 | tfg_get_min_diameter
109 | tfg_get_max_diameter
110 | tfg_get_finger_setup
111 | sdr_stop
112 | sdr_start
113 | sdr_stop_gently
114 | sdr_set_button_led
115 | sdr_set_rpm_deviation_level
116 | sdr_set_vibration_limit_level_g
117 | sdr_get_all_variables
118 | sdr_get_all_double_variables
119 | sdr_get_all_integer_variables
120 | sdr_get_all_boolean_variables
121 | sdr_get_status
122 | sdr_get_warning
123 | sdr_get_current_rpm
124 | sdr_get_current_temp_c
125 | sdr_get_motor_voltage_v
126 | sdr_get_motor_power_w
127 | sdr_get_max_rpm_deviation_of_cycle
128 | sdr_get_vibration_g
129 | sdr_get_rpm_deviation_level
130 | sdr_get_vibration_limit_level_g
131 | sdr_get_accelerometer_x
132 | sdr_get_accelerometer_y
133 | sdr_get_accelerometer_z
134 | sdr_get_gyroscope_x
135 | sdr_get_gyroscope_y
136 | sdr_get_gyroscope_z
137 | sdr_get_ramp_up_speed
138 | sdr_get_ramp_down_speed
139 | sdr_get_pid_constant_p
140 | sdr_get_pid_constant_i
141 | sdr_get_pid_constant_d
142 | sdr_get_temp_limit_level_c
143 | sdr_get_disc_diameter
144 | sdr_get_orbit_size
145 | sdr_get_power_cycle_count
146 | sdr_get_over_temperature_count
147 | sdr_get_power_on_time_sec
148 | sdr_get_vibration_halt_count
149 | sdr_get_motor_on_time_sec
150 | sdr_get_rpm_deviation_count
151 | sdr_get_average_temperature
152 | sdr_get_average_vibration
153 | sdr_get_average_motor_speed
154 | sdr_get_average_motor_power
155 | sdr_get_motor_stopped
156 | sdr_get_motor_running
157 | sdr_get_motor_ramping_up
158 | sdr_get_motor_ramping_down
159 | sdr_get_button_pressed
160 | sdr_get_active_time_sec
161 | sdr_get_target_rpm
162 | sdr_get_error_flags
163 | sdr_clear_active_time_sec
164 | sdr_set_active_time_f3d_limit
165 | twofg_grip_external
166 | twofg_grip_internal
167 | twofg_stop
168 | twofg_set_finger_length
169 | twofg_set_finger_height
170 | twofg_set_finger_orientation
171 | twofg_set_fingertip_offset
172 | twofg_get_all_variables
173 | twofg_get_all_double_variables
174 | twofg_get_all_integer_variables
175 | twofg_get_all_boolean_variables
176 | twofg_get_status
177 | twofg_get_external_width
178 | twofg_get_internal_width
179 | twofg_get_min_external_width
180 | twofg_get_min_internal_width
181 | twofg_get_max_external_width
182 | twofg_get_max_internal_width
183 | twofg_get_force
184 | twofg_get_max_force
185 | twofg_get_finger_length
186 | twofg_get_finger_height
187 | twofg_get_finger_orientation_outward
188 | twofg_get_fingertip_offset
189 | twofg_get_busy
190 | twofg_get_grip_detected
191 | twofg_get_error_not_calibrated
192 | twofg_get_error_linear_sensor
193 | mg_grip
194 | mg_release
195 | mg_set_finger_settings
196 | mg_auto_calibrate
197 | mg_get_all_variables
198 | mg_get_all_double_variables
199 | mg_get_all_integer_variables
200 | mg_get_all_boolean_variables
201 | mg_get_status
202 | mg_get_magnet_strength_percent
203 | mg_get_error_code
204 | mg_get_finger_type
205 | mg_get_finger_height_mm
206 | mg_get_calibration_day
207 | mg_get_calibration_month
208 | mg_get_calibration_year
209 | mg_get_calibration_epoch
210 | mg_get_calibration_build
211 | mg_get_hall_calibration_day
212 | mg_get_hall_calibration_month
213 | mg_get_hall_calibration_year
214 | mg_get_hall_calibration_hour
215 | mg_get_hall_calibration_minute
216 | mg_get_hall_calibration_epoch
217 | mg_get_auto_calibrate_progress_percent
218 | mg_get_grip_detected
219 | mg_get_part_near
220 | mg_get_busy
221 | mg_get_magnet_strength_not_reached
222 | mg_get_smart_grip_available
223 | mg_get_smart_grip_failed
224 | mg_get_part_dropped
225 | fgp_vg_grip
226 | fgp_grip_external
227 | fgp_fg_stop
228 | fgp_vg_release
229 | fgp_set_fixed_finger_length
230 | fgp_set_fixed_finger_height
231 | fgp_set_fixed_fingertip_offset
232 | fgp_set_moving_finger_length
233 | fgp_set_moving_finger_height
234 | fgp_set_moving_fingertip_offset
235 | fgp_set_vacuum_cups_offset
236 | fgp_get_all_variables
237 | fgp_get_all_double_variables
238 | fgp_get_all_integer_variables
239 | fgp_get_all_boolean_variables
240 | fgp_get_status
241 | fgp_get_external_width
242 | fgp_get_min_external_width
243 | fgp_get_max_external_width
244 | fgp_get_force
245 | fgp_get_max_force
246 | fgp_get_fixed_finger_length
247 | fgp_get_fixed_finger_height
248 | fgp_get_fixed_fingertip_offset
249 | fgp_get_moving_finger_length
250 | fgp_get_moving_finger_height
251 | fgp_get_moving_fingertip_offset
252 | fgp_get_vg_vacuum_percent
253 | fgp_get_vg_grip_status
254 | fgp_get_vg_release_status
255 | fgp_get_busy
256 | fgp_get_fg_grip_detected
257 | fgp_get_error_motor_not_calibrated
258 | fgp_get_error_solenoid_not_calibrated
259 | fgp_get_error_encoders_not_calibrated
260 |
261 |
262 |
263 |
--------------------------------------------------------------------------------
/onRobot/onRobot/gripper.py:
--------------------------------------------------------------------------------
1 | import pycurl
2 | import xmlrpc.client
3 | from io import BytesIO
4 |
5 | # https://onrobot.com/sites/default/files/documents/VG10_Vacuun_Gripper_User_Manual_V1.1.1.pdf
6 | class VG10:
7 | def __init__(self, robot_ip, vg_id):
8 | self.vg_id = vg_id
9 | self.robot_ip = robot_ip
10 |
11 | def vg10_release(self, channelA: bool = True, channelB: bool = True):
12 |
13 | self.channelA = channelA # True/False
14 | self.channelB = channelB # True/False
15 |
16 | xml_request = f"""
17 |
18 | vg10_release
19 |
20 |
21 | {self.vg_id}
22 |
23 |
24 | {self.channelA}
25 |
26 |
27 | {self.channelB}
28 |
29 |
30 | """
31 |
32 | headers = ["Content-Type: application/x-www-form-urlencoded"]
33 |
34 | # headers = ["User-Agent: Python-PycURL", "Accept: application/json"]
35 | data = xml_request.replace('\r\n','').encode()
36 | # Create a new cURL object
37 | curl = pycurl.Curl()
38 |
39 | # Set the URL to fetch
40 | curl.setopt(curl.URL, f'http://{self.robot_ip}:41414')
41 | curl.setopt(curl.HTTPHEADER, headers)
42 | curl.setopt(curl.POSTFIELDS, data)
43 | # Create a BytesIO object to store the response
44 | buffer = BytesIO()
45 | curl.setopt(curl.WRITEDATA, buffer)
46 |
47 | # Perform the request
48 | curl.perform()
49 |
50 | # Get the response body
51 | response = buffer.getvalue()
52 |
53 | # Print the response
54 | print(response.decode('utf-8'))
55 |
56 | # Close the cURL object
57 | curl.close()
58 |
59 | def vg10_grip(self, channel, vacuum_percent):
60 |
61 | self.channel = channel # 0,1,2
62 | self.vacuum_percent = vacuum_percent # softgrip => 30 = 30%, firm grip => 60 = 60%
63 |
64 | xml_request = f"""
65 |
66 | vg10_grip
67 |
68 |
69 | {self.vg_id}
70 |
71 |
72 | {self.channel}
73 |
74 |
75 | {self.vacuum_percent}
76 |
77 |
78 |
79 | """
80 |
81 | headers = ["Content-Type: application/x-www-form-urlencoded"]
82 |
83 | # headers = ["User-Agent: Python-PycURL", "Accept: application/json"]
84 | data = xml_request.replace('\r\n','').encode()
85 | # Create a new cURL object
86 | curl = pycurl.Curl()
87 |
88 | # Set the URL to fetch
89 | curl.setopt(curl.URL, f'http://{self.robot_ip}:41414')
90 | curl.setopt(curl.HTTPHEADER, headers)
91 | curl.setopt(curl.POSTFIELDS, data)
92 | # Create a BytesIO object to store the response
93 | buffer = BytesIO()
94 | curl.setopt(curl.WRITEDATA, buffer)
95 |
96 | # Perform the request
97 | curl.perform()
98 |
99 | # Get the response body
100 | response = buffer.getvalue()
101 |
102 | # Print the response
103 | print(response.decode('utf-8'))
104 |
105 | # Close the cURL object
106 | curl.close()
107 |
108 |
109 | class RG2:
110 | def __init__(self, robot_ip, rg_id):
111 | self.rg_id = rg_id
112 | self.robot_ip = robot_ip
113 |
114 | def get_rg_width(self):
115 | xml_request = f"""
116 |
117 | rg_get_width
118 |
119 |
120 | {self.rg_id}
121 |
122 |
123 | """
124 |
125 | headers = ["Content-Type: application/x-www-form-urlencoded"]
126 |
127 | data = xml_request.replace('\r\n','').encode()
128 |
129 | # Create a new cURL object
130 | curl = pycurl.Curl()
131 |
132 | # Set the URL to fetch
133 | curl.setopt(curl.URL, f'http://{self.robot_ip}:41414')
134 | curl.setopt(curl.HTTPHEADER, headers)
135 | curl.setopt(curl.POSTFIELDS, data)
136 | # Create a BytesIO object to store the response
137 | buffer = BytesIO()
138 | curl.setopt(curl.WRITEDATA, buffer)
139 |
140 | # Perform the request
141 | curl.perform()
142 |
143 | # Get the response body
144 | response = buffer.getvalue()
145 |
146 | # Print the response
147 | print(response.decode('utf-8'))
148 |
149 | # Close the cURL object
150 | curl.close()
151 |
152 | xml_response = xmlrpc.client.loads(response.decode('utf-8'))
153 | rg_width = float(xml_response[0][0])
154 | #print(rg_width)
155 | return rg_width
156 |
157 |
158 | def rg_grip(self, target_width: float = 100, target_force: float= 10) -> bool:
159 | #assert target_width <= 100 and target_width >= 0, 'Target Width must be within the range [0,100]'
160 | #assert target_force <= 40 or target_force >= 0, 'Target force must be within the range [0,40]'
161 |
162 | # WARNING: params will be sent straight to electrical system with no error checking on robot!
163 | # if (target_width > 100):
164 | # target_width = 100
165 | # if(target_width < 0):
166 | # target_width = 0
167 | # if(target_force > 40):
168 | # target_force = 40
169 | # if(target_force < 0):
170 | # target_force = 0
171 |
172 | xml_request = f"""
173 |
174 | rg_grip
175 |
176 |
177 | {self.rg_id}
178 |
179 |
180 | {target_width}
181 |
182 |
183 | {target_force}
184 |
185 |
186 | """
187 |
188 | headers = ["Content-Type: application/x-www-form-urlencoded"]
189 |
190 | # headers = ["User-Agent: Python-PycURL", "Accept: application/json"]
191 | data = xml_request.replace('\r\n','').encode()
192 | # Create a new cURL object
193 | curl = pycurl.Curl()
194 |
195 | # Set the URL to fetch
196 | curl.setopt(curl.URL, f'http://{self.robot_ip}:41414')
197 | curl.setopt(curl.HTTPHEADER, headers)
198 | curl.setopt(curl.POSTFIELDS, data)
199 | # Create a BytesIO object to store the response
200 | buffer = BytesIO()
201 | curl.setopt(curl.WRITEDATA, buffer)
202 |
203 | # Perform the request
204 | curl.perform()
205 |
206 | # Get the response body
207 | response = buffer.getvalue()
208 |
209 | # Print the response
210 | print(response.decode('utf-8'))
211 |
212 | # Close the cURL object
213 | curl.close()
214 |
215 |
216 | class TwoFG7():
217 | def __init__(self, robot_ip: str, id: int):
218 | self.robot_ip = robot_ip
219 | self.id = id
220 |
221 | self.max_force = self.twofg_get_max_force()
222 | self.max_ext_width = self.twofg_get_max_external_width()
223 | self.max_int_width = self.twofg_get_max_internal_width()
224 | self.min_ext_width = self.twofg_get_min_external_width()
225 | self.min_int_width = self.twofg_get_min_internal_width()
226 |
227 | self.gripper_width = [self.twofg_get_external_width(), self.twofg_get_internal_width()]
228 |
229 |
230 | def _send_xml_rpc_request(self, _req=None):
231 |
232 | headers = ["Content-Type: application/x-www-form-urlencoded"]
233 |
234 | data = _req.replace('\r\n','').encode()
235 |
236 | # Create a new cURL object
237 | curl = pycurl.Curl()
238 |
239 | # Set the URL to fetch
240 | curl.setopt(curl.URL, f'http://{self.robot_ip}:41414')
241 | curl.setopt(curl.HTTPHEADER, headers)
242 | curl.setopt(curl.POSTFIELDS, data)
243 | # Create a BytesIO object to store the response
244 | buffer = BytesIO()
245 | curl.setopt(curl.WRITEDATA, buffer)
246 |
247 | # Perform the request
248 | curl.perform()
249 |
250 | # Get the response body
251 | response = buffer.getvalue()
252 |
253 | # Print the response
254 | print(response.decode('utf-8'))
255 |
256 | # Close the cURL object
257 | curl.close()
258 | # Get response from xmlrpc server
259 | xml_response = xmlrpc.client.loads(response.decode('utf-8'))
260 |
261 | return xml_response[0][0]
262 |
263 | def twofg_get_external_width(self) -> float:
264 | xml_request = f"""
265 |
266 | twofg_get_external_width
267 |
268 |
269 | {self.id}
270 |
271 |
272 | """
273 |
274 | return float(self._send_xml_rpc_request(xml_request))
275 |
276 | def twofg_get_internal_width(self) -> float:
277 | xml_request = f"""
278 |
279 | twofg_get_internal_width
280 |
281 |
282 | {self.id}
283 |
284 |
285 | """
286 |
287 | return float(self._send_xml_rpc_request(xml_request))
288 |
289 |
290 | def twofg_grip_external(self, target_width: float = 40.00, target_force: int= 20, speed: int=1) -> int:
291 | """
292 | speed is the range from 1 to 100. It represents the percentage of the maximum speed.
293 | """
294 | assert target_width <= self.max_ext_width and target_width >= self.min_ext_width, f'Target Width must be within the range [{self.min_ext_width},{self.max_ext_width}]'
295 | assert target_force <= self.max_force or target_force >= 20, f'Target force must be within the range [20,{self.max_force}]'
296 |
297 | # WARNING: params will be sent straight to electrical system with no error checking on robot!
298 | if (target_width > self.max_ext_width):
299 | target_width = self.max_ext_width
300 | if(target_width < self.min_ext_width):
301 | target_width = self.min_ext_width
302 | if(target_force > self.max_force):
303 | target_force = self.max_force
304 | if(target_force < 20):
305 | target_force = 20
306 |
307 | xml_request = f"""
308 |
309 | twofg_grip_external
310 |
311 |
312 | {self.id}
313 |
314 |
315 | {target_width}
316 |
317 |
318 | {target_force}
319 |
320 |
321 | {speed}
322 |
323 |
324 | """
325 |
326 | # if status != 0, then command not succesful. Perhaps there is no space to move the gripper
327 | return int(self._send_xml_rpc_request(xml_request))
328 |
329 | def twofg_ext_release(self, target_width: float = 40.00, speed: int=1) -> int:
330 | """
331 | speed is the range from 1 to 100. It represents the percentage of the maximum speed.
332 | """
333 | target_force: int= 80
334 |
335 | assert target_width <= self.max_ext_width and target_width >= self.min_ext_width, f'Target Width must be within the range [{self.min_ext_width},{self.max_ext_width}]'
336 | assert target_force <= self.max_force or target_force >= 20, f'Target force must be within the range [20,{self.max_force}]'
337 |
338 | # WARNING: params will be sent straight to electrical system with no error checking on robot!
339 | if (target_width > self.max_ext_width):
340 | target_width = self.max_ext_width
341 | if(target_width < self.min_ext_width):
342 | target_width = self.min_ext_width
343 | if(target_force > self.max_force):
344 | target_force = self.max_force
345 | if(target_force < 20):
346 | target_force = 20
347 |
348 | xml_request = f"""
349 |
350 | twofg_grip_external
351 |
352 |
353 | {self.id}
354 |
355 |
356 | {target_width}
357 |
358 |
359 | {target_force}
360 |
361 |
362 | {speed}
363 |
364 |
365 | """
366 |
367 | # if status != 0, then command not succesful. Perhaps there is no space to move the gripper
368 | return int(self._send_xml_rpc_request(xml_request))
369 |
370 | def twofg_grip_internal(self, target_width: float = 40.00, target_force: int= 10, speed: int=1) -> int:
371 | """
372 | speed is the range from 1 to 100. It represents the percentage of the maximum speed.
373 | """
374 | assert target_width <= self.max_int_width and target_width >= self.min_int_width, f'Target Width must be within the range [{self.min_int_width},{self.max_int_width}]'
375 | assert target_force <= self.max_force or target_force >= 20, f'Target force must be within the range [20,{self.max_force}]'
376 |
377 | # WARNING: params will be sent straight to electrical system with no error checking on robot!
378 | if (target_width > self.max_int_width):
379 | target_width = self.max_int_width
380 | if(target_width < self.min_int_width):
381 | target_width = self.min_int_width
382 | if(target_force > self.max_force):
383 | target_force = self.max_force
384 | if(target_force < 20):
385 | target_force = 20
386 |
387 | xml_request = f"""
388 |
389 | twofg_grip_internal
390 |
391 |
392 | {self.id}
393 |
394 |
395 | {target_width}
396 |
397 |
398 | {target_force}
399 |
400 |
401 | {speed}
402 |
403 |
404 | """
405 |
406 | # if status != 0, then command not succesful. Perhaps there is no space to move the gripper
407 | return int(self._send_xml_rpc_request(xml_request))
408 |
409 | def twofg_int_release(self, target_width: float = 40.00, speed: int=1) -> int:
410 | """
411 | speed is the range from 1 to 100. It represents the percentage of the maximum speed.
412 | """
413 | target_force: int= 80
414 |
415 | assert target_width <= self.max_int_width and target_width >= self.min_int_width, f'Target Width must be within the range [{self.min_int_width},{self.max_int_width}]'
416 | assert target_force <= self.max_force or target_force >= 20, f'Target force must be within the range [20,{self.max_force}]'
417 |
418 | # WARNING: params will be sent straight to electrical system with no error checking on robot!
419 | if (target_width > self.max_int_width):
420 | target_width = self.max_int_width
421 | if(target_width < self.min_int_width):
422 | target_width = self.min_int_width
423 | if(target_force > self.max_force):
424 | target_force = self.max_force
425 | if(target_force < 20):
426 | target_force = 20
427 |
428 | xml_request = f"""
429 |
430 | twofg_grip_internal
431 |
432 |
433 | {self.id}
434 |
435 |
436 | {target_width}
437 |
438 |
439 | {target_force}
440 |
441 |
442 | {speed}
443 |
444 |
445 | """
446 |
447 | # if status != 0, then command not succesful. Perhaps there is no space to move the gripper
448 | return int(self._send_xml_rpc_request(xml_request))
449 |
450 | def twofg_get_max_external_width(self) -> float:
451 | xml_request = f"""
452 |
453 | twofg_get_max_external_width
454 |
455 |
456 | {self.id}
457 |
458 |
459 | """
460 |
461 | return float(self._send_xml_rpc_request(xml_request))
462 |
463 | def twofg_get_max_internal_width(self) -> float:
464 | xml_request = f"""
465 |
466 | twofg_get_max_internal_width
467 |
468 |
469 | {self.id}
470 |
471 |
472 | """
473 |
474 | return float(self._send_xml_rpc_request(xml_request))
475 |
476 | def twofg_get_min_external_width(self) -> float:
477 | xml_request = f"""
478 |
479 | twofg_get_min_external_width
480 |
481 |
482 | {self.id}
483 |
484 |
485 | """
486 |
487 | return float(self._send_xml_rpc_request(xml_request))
488 |
489 | def twofg_get_min_internal_width(self) -> float:
490 | xml_request = f"""
491 |
492 | twofg_get_min_internal_width
493 |
494 |
495 | {self.id}
496 |
497 |
498 | """
499 |
500 | return float(self._send_xml_rpc_request(xml_request))
501 |
502 | def twofg_get_max_force(self) -> int:
503 | xml_request = f"""
504 |
505 | twofg_get_max_force
506 |
507 |
508 | {self.id}
509 |
510 |
511 | """
512 |
513 | return int(self._send_xml_rpc_request(xml_request))
514 |
515 | def twofg_get_status(self) -> int:
516 | # The status codes are not fully clear.
517 | # sofar:
518 | # 0: no grip
519 | # 2: has gripped an object
520 |
521 | xml_request = f"""
522 |
523 | twofg_get_status
524 |
525 |
526 | {self.id}
527 |
528 |
529 | """
530 |
531 | return int(self._send_xml_rpc_request(xml_request))
532 |
533 | def twofg_get_busy(self) -> bool:
534 | xml_request = f"""
535 |
536 | twofg_get_busy
537 |
538 |
539 | {self.id}
540 |
541 |
542 | """
543 |
544 | return bool(self._send_xml_rpc_request(xml_request))
545 |
546 | def twofg_get_grip_detected(self) -> bool:
547 | xml_request = f"""
548 |
549 | twofg_get_grip_detected
550 |
551 |
552 | {self.id}
553 |
554 |
555 | """
556 |
557 | return bool(self._send_xml_rpc_request(xml_request))
558 |
559 | def main():
560 |
561 | # Default id is zero, if you have multiple grippers,
562 | # see logs in UR Teach Pendant to know which is which :)
563 | print("Main")
564 | rg_id = 0
565 | ip = "192.168.56.101"
566 | rg_gripper = RG2(ip,rg_id)
567 |
568 | rg_width = rg_gripper.get_rg_width()
569 | print("rg_width: ",rg_width)
570 |
571 | target_force = 40.00
572 |
573 | rg_gripper.rg_grip(100.0, target_force)
574 |
575 |
576 |
577 | if __name__ == "__main__":
578 | main()
--------------------------------------------------------------------------------
/UOY-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------