├── .gitignore
├── .readthedocs.yaml
├── LICENSE
├── Pipfile
├── Pipfile.lock
├── README.md
├── __init__.py
├── docs
├── .gitignore
├── Makefile
├── api.rst
├── conf.py
├── index.rst
├── make.bat
├── requirements.in
├── requirements.txt
└── usage.rst
├── pyRobotiqGripper.py
├── pyproject.toml
├── requirements.txt
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | venv
2 | __pycache__
3 | pyRobotiqGripper.egg-info/
4 | dist/
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yaml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | # Set the OS, Python version and other tools you might need
9 | build:
10 | os: ubuntu-22.04
11 | tools:
12 | python: "3.12"
13 | # You can also specify other tool versions:
14 | # nodejs: "19"
15 | # rust: "1.64"
16 | # golang: "1.19"
17 |
18 | # Build documentation in the "docs/" directory with Sphinx
19 | sphinx:
20 | configuration: docs/conf.py
21 |
22 | # Optionally build your docs in additional formats such as PDF and ePub
23 | # formats:
24 | # - pdf
25 | # - epub
26 |
27 | # Optional but recommended, declare the Python requirements required
28 | # to build your documentation
29 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
30 | python:
31 | install:
32 | - requirements: docs/requirements.txt
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [2024] [Benoit CASTETS]
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.
--------------------------------------------------------------------------------
/Pipfile:
--------------------------------------------------------------------------------
1 | [[source]]
2 | url = "https://pypi.org/simple"
3 | verify_ssl = true
4 | name = "pypi"
5 |
6 | [packages]
7 | requests = "*"
8 |
9 | [dev-packages]
10 |
11 | [requires]
12 | python_version = "3.12"
13 |
--------------------------------------------------------------------------------
/Pipfile.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_meta": {
3 | "hash": {
4 | "sha256": "1977acb1ba9778abb66054090e2618a0a1f1759b1b3b32afd8a7d404ba18b4fb"
5 | },
6 | "pipfile-spec": 6,
7 | "requires": {
8 | "python_version": "3.12"
9 | },
10 | "sources": [
11 | {
12 | "name": "pypi",
13 | "url": "https://pypi.org/simple",
14 | "verify_ssl": true
15 | }
16 | ]
17 | },
18 | "default": {
19 | "certifi": {
20 | "hashes": [
21 | "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f",
22 | "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"
23 | ],
24 | "markers": "python_version >= '3.6'",
25 | "version": "==2024.2.2"
26 | },
27 | "charset-normalizer": {
28 | "hashes": [
29 | "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027",
30 | "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087",
31 | "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786",
32 | "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8",
33 | "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09",
34 | "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185",
35 | "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574",
36 | "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e",
37 | "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519",
38 | "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898",
39 | "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269",
40 | "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3",
41 | "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f",
42 | "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6",
43 | "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8",
44 | "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a",
45 | "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73",
46 | "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc",
47 | "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714",
48 | "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2",
49 | "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc",
50 | "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce",
51 | "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d",
52 | "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e",
53 | "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6",
54 | "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269",
55 | "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96",
56 | "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d",
57 | "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a",
58 | "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4",
59 | "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77",
60 | "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d",
61 | "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0",
62 | "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed",
63 | "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068",
64 | "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac",
65 | "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25",
66 | "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8",
67 | "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab",
68 | "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26",
69 | "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2",
70 | "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db",
71 | "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f",
72 | "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5",
73 | "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99",
74 | "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c",
75 | "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d",
76 | "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811",
77 | "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa",
78 | "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a",
79 | "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03",
80 | "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b",
81 | "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04",
82 | "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c",
83 | "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001",
84 | "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458",
85 | "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389",
86 | "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99",
87 | "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985",
88 | "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537",
89 | "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238",
90 | "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f",
91 | "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d",
92 | "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796",
93 | "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a",
94 | "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143",
95 | "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8",
96 | "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c",
97 | "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5",
98 | "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5",
99 | "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711",
100 | "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4",
101 | "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6",
102 | "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c",
103 | "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7",
104 | "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4",
105 | "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b",
106 | "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae",
107 | "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12",
108 | "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c",
109 | "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae",
110 | "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8",
111 | "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887",
112 | "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b",
113 | "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4",
114 | "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f",
115 | "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5",
116 | "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33",
117 | "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
118 | "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
119 | ],
120 | "markers": "python_full_version >= '3.7.0'",
121 | "version": "==3.3.2"
122 | },
123 | "idna": {
124 | "hashes": [
125 | "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc",
126 | "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"
127 | ],
128 | "markers": "python_version >= '3.5'",
129 | "version": "==3.7"
130 | },
131 | "requests": {
132 | "hashes": [
133 | "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
134 | "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
135 | ],
136 | "index": "pypi",
137 | "markers": "python_version >= '3.7'",
138 | "version": "==2.31.0"
139 | },
140 | "urllib3": {
141 | "hashes": [
142 | "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
143 | "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
144 | ],
145 | "markers": "python_version >= '3.8'",
146 | "version": "==2.2.1"
147 | }
148 | },
149 | "develop": {}
150 | }
151 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | pyRobotiqGripper
2 | =================
3 |
4 | Python Driver for Robotiq Grippers via Modbus RTU
5 |
6 | pyRobotiqGripper is a Python library designed to facilitate control of Robotiq grippers using Modbus RTU communication via serial port.
7 | It is compatible with 2F85, 2F140, and Hande.
8 |
9 | Documentation: `pyRobotiqGripper Documentation `_
10 |
11 | Disclaimer
12 | ----------
13 |
14 | This library can be seen as a starting point for a Robotiq integration project.
15 | You are responsible for what you do with this library.
16 | The author takes no responsibility for any malfunction.
17 |
18 | Note: This library is not maintained by Robotiq.
19 |
20 | How to Install
21 | --------------
22 |
23 | Install the pyRobotiqGripper python package using PIP.
24 |
25 | ```bash
26 |
27 | python -m pip install pyRobotiqGripper
28 | ```
29 | Typical Usage
30 | -------------
31 |
32 | Import the pyRobotiqGripper module.
33 |
34 | ```python
35 | import pyRobotiqGripper
36 | ```
37 | Create a Robotiq gripper object.
38 |
39 | ```python
40 | gripper = pyRobotiqGripper()
41 | ```
42 | By default, the serial port on which the gripper is connected is automatically detected. However, you can manually specify the serial port name if you want to. Refer to the API documentation for more information.
43 | You can now activate the gripper and eventually calibrate the gripper if you want to control the opening in mm instead of bit.
44 |
45 | Note: During activation, the gripper is going to fully open and close. Do not disturb this process. Do not place an object inside the gripper.
46 |
47 | Note: The gripper finger position varies from 0 to 255. It is coded on 8 bits.
48 |
49 | ```python
50 | gripper.activate()
51 | gripper.calibrate(0, 40)
52 | ```
53 | You can now do whatever you want with the gripper: open, close, get position feedback, etc.
54 |
55 | ```python
56 | gripper.open()
57 | gripper.close()
58 | gripper.goTo(100)
59 | position_in_bit = gripper.getPosition()
60 | print(position_in_bit)
61 | gripper.goTomm(25)
62 | position_in_mm = gripper.getPositionmm()
63 | print(position_in_mm)
64 | ```
65 |
66 | You can print the current status of gripper registers using printInfo.
67 |
68 | ```python
69 | gripper.printInfo()
70 | ```
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/castetsb/pyRobotiqGripper/5052fef0387e9f23b7b602967cb3ffd4e357ab67/__init__.py
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | _build/
2 | _themes/
3 | .static
4 | pyRobotiqGripper.egg-info/
5 | dist/
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/api.rst:
--------------------------------------------------------------------------------
1 | .. _api:
2 |
3 | API
4 | ===
5 |
6 | .. automodule:: pyRobotiqGripper
7 | :members:
8 | :undoc-members:
9 | :show-inheritance:
10 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # For the full list of built-in configuration values, see the documentation:
4 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
5 |
6 | # -- Project information -----------------------------------------------------
7 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
8 |
9 | import os
10 | import sys
11 |
12 | # Get the project root dir, which is the parent dir of this
13 | cwd = os.getcwd()
14 | project_root = os.path.dirname(cwd)
15 |
16 |
17 |
18 | # Insert the project root dir as the first element in the PYTHONPATH.
19 | # This lets us ensure that the source package is imported, and that its
20 | # version is used.
21 | sys.path.insert(0, project_root)
22 |
23 | project = 'pyRobotiqGripper'
24 | copyright = '2024, Benoit CASTETS'
25 | author = 'Benoit CASTETS'
26 | release = '1.0'
27 |
28 | # -- General configuration ---------------------------------------------------
29 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
30 |
31 | extensions = [
32 | "sphinx.ext.todo",
33 | "sphinx.ext.viewcode",
34 | "sphinx.ext.autodoc",
35 | "sphinx.ext.autosummary",
36 | "sphinx.ext.duration"]
37 |
38 | templates_path = ['_templates']
39 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
40 |
41 |
42 |
43 | # -- Options for HTML output -------------------------------------------------
44 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
45 |
46 | html_theme = 'sphinx_rtd_theme'
47 | html_static_path = ['_static']
48 |
49 | """
50 | Tells the project to use sphinx pygments for color coding code examples.
51 | """
52 |
53 | pygments_style = 'sphinx'
54 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. pyRobotiqGripper documentation master file, created by
2 | sphinx-quickstart on Sat Apr 27 22:18:12 2024.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | .. include:: ../README.md
7 |
8 | .. toctree::
9 | :maxdepth: 2
10 | :caption: Contents:
11 |
12 | Home
13 | api
14 |
15 | Indices and tables
16 | ==================
17 |
18 | * :ref:`genindex`
19 | * :ref:`modindex`
20 | * :ref:`search`
21 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 |
13 | %SPHINXBUILD% >NUL 2>NUL
14 | if errorlevel 9009 (
15 | echo.
16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17 | echo.installed, then set the SPHINXBUILD environment variable to point
18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
19 | echo.may add the Sphinx directory to PATH.
20 | echo.
21 | echo.If you don't have Sphinx installed, grab it from
22 | echo.https://www.sphinx-doc.org/
23 | exit /b 1
24 | )
25 |
26 | if "%1" == "" goto help
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/requirements.in:
--------------------------------------------------------------------------------
1 | sphinx
2 | sphinx_rtd_theme
3 | minimalmodbus
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.12
3 | # by the following command:
4 | #
5 | # pip-compile docs/requirements.in
6 | #
7 | alabaster==0.7.16
8 | # via sphinx
9 | babel==2.14.0
10 | # via sphinx
11 | certifi==2024.2.2
12 | # via requests
13 | charset-normalizer==3.3.2
14 | # via requests
15 | colorama==0.4.6
16 | # via sphinx
17 | docutils==0.20.1
18 | # via
19 | # sphinx
20 | # sphinx-rtd-theme
21 | idna==3.7
22 | # via requests
23 | imagesize==1.4.1
24 | # via sphinx
25 | jinja2==3.1.3
26 | # via sphinx
27 | markupsafe==2.1.5
28 | # via jinja2
29 | minimalmodbus==2.1.1
30 | # via -r docs/requirements.in
31 | packaging==24.0
32 | # via sphinx
33 | pygments==2.17.2
34 | # via sphinx
35 | pyserial==3.5
36 | # via minimalmodbus
37 | requests==2.31.0
38 | # via sphinx
39 | snowballstemmer==2.2.0
40 | # via sphinx
41 | sphinx==7.3.7
42 | # via
43 | # -r docs/requirements.in
44 | # sphinx-rtd-theme
45 | # sphinxcontrib-jquery
46 | sphinx-rtd-theme==2.0.0
47 | # via -r docs/requirements.in
48 | sphinxcontrib-applehelp==1.0.8
49 | # via sphinx
50 | sphinxcontrib-devhelp==1.0.6
51 | # via sphinx
52 | sphinxcontrib-htmlhelp==2.0.5
53 | # via sphinx
54 | sphinxcontrib-jquery==4.1
55 | # via sphinx-rtd-theme
56 | sphinxcontrib-jsmath==1.0.1
57 | # via sphinx
58 | sphinxcontrib-qthelp==1.0.7
59 | # via sphinx
60 | sphinxcontrib-serializinghtml==1.1.10
61 | # via sphinx
62 | urllib3==2.2.1
63 | # via requests
64 |
--------------------------------------------------------------------------------
/docs/usage.rst:
--------------------------------------------------------------------------------
1 | Usage
2 | =====
3 |
4 |
5 | .. _installation:
6 |
7 | Installation
8 | ------------
9 |
10 | Under construction.
11 |
--------------------------------------------------------------------------------
/pyRobotiqGripper.py:
--------------------------------------------------------------------------------
1 | """pyRobotiqGripper: Python Driver for Robotiq Grippers via Modbus RTU
2 |
3 | pyRobotiqGripper is a Python library designed to facilitate control of Robotiq\
4 | grippers using Modbus RTU communication via serial port.
5 |
6 | This module provides documentation in two formats:
7 |
8 | - Docstrings: Embedded within the code for easy access.
9 | - Online Documentation: Extensive documentation available at\
10 | .
11 | """
12 |
13 | #General information
14 | __author__ = "Benoit CASTETS"
15 | __email__ = "opensourceeng@robotiq.com"
16 | __license__ = "Apache License, Version 2.0"
17 | __url__ = "https://github.com/castetsb/pyRobotiqGripper"
18 | __version__ = "1.0.0"
19 |
20 | #Iport libraries
21 | import minimalmodbus as mm
22 | import time
23 | import serial
24 | import serial.tools.list_ports
25 |
26 | #Constants
27 | BAUDRATE=115200
28 | BYTESIZE=8
29 | PARITY="N"
30 | STOPBITS=1
31 | TIMEOUT=0.2
32 | AUTO_DETECTION="auto"
33 |
34 | class RobotiqGripper( mm.Instrument ):
35 | """Object control Robotiq grippers (2F85, 2F140 or hande).
36 |
37 | Suppose that the gripper is connected via the USB/RS485 adapter to the PC\
38 | executing this code.
39 |
40 | Modbus RTU function code supported by robotiq gripper
41 |
42 | ======================================= ====================
43 | Description Modbus function code
44 | ======================================= ====================
45 | Read registers 4
46 | Write registers 16
47 | Master read & write multiple registers 23
48 | ======================================= ====================
49 |
50 | For more information for gripper communication please check gripper manual
51 | on Robotiq website.
52 | https://robotiq.com/support/2f-85-2f-140
53 |
54 | .. note::
55 | This object cannot be use to control epick, 3F or powerpick.
56 | """
57 |
58 | def __init__(self, portname=AUTO_DETECTION,slaveAddress=9):
59 | """Create a RobotiqGripper object whic can be use to control Robotiq\
60 | grippers using modbus RTU protocol USB/RS485 connection.
61 |
62 | Args:
63 | - portname (str, optional): The serial port name, for example\
64 | /dev/ttyUSB0 (Linux), /dev/tty.usbserial (OS X) or COM4\
65 | (Windows). It is necesary to allowpermission to access this\
66 | connection using the bash comman sudo chmod 666 /dev/ttyUSB0.\
67 | By default the portname is set to "auto". In this case the\
68 | connection is done with the first gripper found as connected\
69 | to the PC.
70 | - slaveaddress (int, optional): Address of the gripper (integer)\
71 | usually 9.
72 | """
73 | #Gripper salve address
74 | self.slaveAddress=slaveAddress
75 |
76 | #Port on which is connected the gripper
77 | if portname == "auto":
78 | self.portname=self._autoConnect()
79 | if self.portname is None:
80 | raise Exception("No gripper detected")
81 | else:
82 | self.portname=portname
83 |
84 | #Create a pyserial object to connect to the gripper
85 | ser=serial.Serial(self.portname,
86 | BAUDRATE,
87 | BYTESIZE,
88 | PARITY,
89 | STOPBITS,
90 | TIMEOUT)
91 |
92 | #Create the object using parent class contructor
93 | super().__init__(ser,
94 | self.slaveAddress,
95 | mm.MODE_RTU,
96 | close_port_after_each_call=False,
97 | debug=False)
98 |
99 | #Attribute to monitore if the gripper is processing an action
100 | self.processing=False
101 |
102 | #Maximum allowed time to perform and action
103 | self.timeOut=10
104 |
105 | #Dictionnary where are stored description of each register state
106 | self.registerDic={}
107 | self._buildRegisterDic()
108 |
109 |
110 | #Dictionnary where are stored register values retrived from the gripper
111 | self.paramDic={}
112 | self.readAll()
113 |
114 | #Attributes to store open and close distance state information
115 |
116 | #Distance between the fingers when gripper is closed
117 | self.closemm=None
118 | #Position in bit when gripper is closed
119 | self.closebit=None
120 |
121 | #Distance between the fingers when gripper is open
122 | self.openmm=None
123 | #Position in bit when gripper is open
124 | self.openbit=None
125 |
126 | self._aCoef=None
127 | self._bCoef=None
128 |
129 | def _autoConnect(self):
130 | """Return the name of the port on which is connected the gripper
131 | """
132 | ports=serial.tools.list_ports.comports()
133 | portName=None
134 |
135 | for port in ports:
136 | try:
137 | # Try opening the port
138 | ser = serial.Serial(port.device,BAUDRATE,BYTESIZE,PARITY,STOPBITS,TIMEOUT)
139 |
140 | device=mm.Instrument(ser,self.slaveAddress,mm.MODE_RTU,close_port_after_each_call=False,debug=False)
141 |
142 | #Try to write the position 100
143 | device.write_registers(1000,[0,100,0])
144 |
145 | #Try to read the position request eco
146 | registers=device.read_registers(2000,3,4)
147 | posRequestEchoReg3=registers[1] & 0b0000000011111111
148 |
149 | #Check if position request eco reflect the requested position
150 | if posRequestEchoReg3 != 100:
151 | raise Exception("Not a gripper")
152 | portName=port.device
153 | del device
154 |
155 | ser.close() # Close the port
156 | except:
157 | pass # Skip if port cannot be opened
158 |
159 | # If no suitable port is found
160 | return portName
161 |
162 | def _buildRegisterDic(self):
163 | """Build a dictionnary with comment to explain each register variable.
164 |
165 | Dictionnary key are variable names. Dictionnary value are dictionnary\
166 | with comments about each statut of the variable (key=variable value,\
167 | value=comment)
168 | """
169 | ######################################################################
170 | #input register variable
171 | self.registerDic.update({"gOBJ":{},"gSTA":{},"gGTO":{},"gACT":{},
172 | "kFLT":{},"gFLT":{},"gPR":{},"gPO":{},"gCU":{}})
173 |
174 | #gOBJ
175 | gOBJdic=self.registerDic["gOBJ"]
176 |
177 | gOBJdic[0]="Fingers are in motion towards requested position. No\
178 | object detected."
179 | gOBJdic[1]="Fingers have stopped due to a contact while opening before\
180 | requested position. Object detected opening."
181 | gOBJdic[2]="Fingers have stopped due to a contact while closing before\
182 | requested position. Object detected closing."
183 | gOBJdic[3]="Fingers are at requested position. No object detected or\
184 | object has been loss / dropped."
185 |
186 | #gSTA
187 | gSTAdic=self.registerDic["gSTA"]
188 |
189 | gSTAdic[0]="Gripper is in reset ( or automatic release ) state. See\
190 | Fault Status if Gripper is activated."
191 | gSTAdic[1]="Activation in progress."
192 | gSTAdic[3]="Activation is completed."
193 |
194 | #gGTO
195 | gGTOdic=self.registerDic["gGTO"]
196 |
197 | gGTOdic[0]="Stopped (or performing activation / automatic release)."
198 | gGTOdic[1]="Go to Position Request."
199 | gGTOdic[2]="Unknown status"
200 | gGTOdic[3]="Unknown status"
201 |
202 | #gACT
203 | gACTdic=self.registerDic["gACT"]
204 |
205 | gACTdic[0]="Gripper reset."
206 | gACTdic[1]="Gripper activation."
207 |
208 | #kFLT
209 | kFLTdic=self.registerDic["kFLT"]
210 | i=0
211 | while i<256:
212 | kFLTdic[i]=i
213 | i+=1
214 |
215 | #See your optional Controller Manual (input registers & status).
216 |
217 | #gFLT
218 | gFLTdic=self.registerDic["gFLT"]
219 | i=0
220 | while i<256:
221 | gFLTdic[i]=i
222 | i+=1
223 | gFLTdic[0]="No fault (LED is blue)"
224 | gFLTdic[5]="Priority faults (LED is blue). Action delayed, activation\
225 | (reactivation) must be completed prior to perfmoring the action."
226 | gFLTdic[7]="Priority faults (LED is blue). The activation bit must be\
227 | set prior to action."
228 | gFLTdic[8]="Minor faults (LED continuous red). Maximum operating\
229 | temperature exceeded, wait for cool-down."
230 | gFLTdic[9]="Minor faults (LED continuous red). No communication during\
231 | at least 1 second."
232 | gFLTdic[10]="Major faults (LED blinking red/blue) - Reset is required\
233 | (rising edge on activation bit rACT needed). Under minimum\
234 | operating voltage."
235 | gFLTdic[11]="Major faults (LED blinking red/blue) - Reset is required\
236 | (rising edge on activation bit rACT needed). Automatic release in\
237 | progress."
238 | gFLTdic[12]="Major faults (LED blinking red/blue) - Reset is required\
239 | (rising edge on activation bit rACT needed). Internal fault;\
240 | contact support@robotiq.com."
241 | gFLTdic[13]="Major faults (LED blinking red/blue) - Reset is required\
242 | (rising edge on activation bit rACT needed). Activation fault,\
243 | verify that no interference or other error occurred."
244 | gFLTdic[14]="Major faults (LED blinking red/blue) - Reset is required\
245 | (rising edge on activation bit rACT needed). Overcurrent triggered."
246 | gFLTdic[15]="Major faults (LED blinking red/blue) - Reset is required\
247 | (rising edge on activation bit rACT needed). Automatic release\
248 | completed."
249 |
250 | #gPR
251 | gPRdic=self.registerDic["gPR"]
252 |
253 | i=0
254 | while i<256:
255 | gPRdic[i]="Echo of the requested position for the Gripper:\
256 | {}/255".format(i)
257 | i+=1
258 |
259 | #gPO
260 | gPOdic=self.registerDic["gPO"]
261 | i=0
262 | while i<256:
263 | gPOdic[i]="Actual position of the Gripper obtained via the encoders:\
264 | {}/255".format(i)
265 | i+=1
266 |
267 | #gCU
268 | gCUdic=self.registerDic["gCU"]
269 | i=0
270 | while i<256:
271 | current=i*10
272 | gCUdic[i]="The current is read instantaneously from the motor\
273 | drive, approximate current: {} mA".format(current)
274 | i+=1
275 |
276 |
277 | ######################################################################
278 | #output register variable
279 | self.registerDic.update({"rARD":{},
280 | "rATR":{},
281 | "rGTO":{},
282 | "rACT":{},
283 | "rPR":{},
284 | "rFR":{},
285 | "rSP":{}})
286 |
287 | ######################################################################
288 |
289 | def readAll(self):
290 | """Retrieve gripper output register information and save it in the\
291 | parameter dictionary.
292 |
293 | The dictionary keys are as follows:
294 |
295 | - gOBJ: Object detection status. This built-in feature provides\
296 | information on possible object pick-up. Ignore if gGTO == 0.
297 | - gSTA: Gripper status. Returns the current status and motion of the\
298 | gripper fingers.
299 | - gGTO: Action status. Echo of the rGTO bit (go-to bit).
300 | - gACT: Activation status. Echo of the rACT bit (activation bit).
301 | - kFLT: See your optional controller manual for input registers and\
302 | status.
303 | - gFLT: Fault status. Returns general error messages useful for\
304 | troubleshooting. A fault LED (red) is present on the gripper\
305 | chassis. The LED can be blue, red, or both, and can be solid\
306 | or blinking.
307 | - gPR: Echo of the requested position for the gripper. Value between\
308 | 0x00 and 0xFF.
309 | - gPO: Actual position of the gripper obtained via the encoders.\
310 | Value between 0x00 and 0xFF.
311 | - gCU: The current is read instantaneously from the motor drive. Value\
312 | between 0x00 and 0xFF. Approximate current equivalent is 10 times\
313 | the value read in mA.
314 | """
315 | #Clear parameter dictionnary data
316 | self.paramDic={}
317 |
318 | #Read 3 16bits registers starting from register 2000
319 | registers=self.read_registers(2000,3)
320 |
321 | #########################################
322 | #Register 2000
323 | #First Byte: gripperStatus
324 | #Second Byte: RESERVED
325 |
326 | #First Byte: gripperStatus
327 | gripperStatusReg0=(registers[0] >> 8) & 0b11111111 #xxxxxxxx00000000
328 | #########################################
329 | #Object detection
330 | self.paramDic["gOBJ"]=(gripperStatusReg0 >> 6) & 0b11 #xx000000
331 | #Gripper status
332 | self.paramDic["gSTA"]=(gripperStatusReg0 >> 4) & 0b11 #00xx0000
333 | #Action status. echo of rGTO (go to bit)
334 | self.paramDic["gGTO"]=(gripperStatusReg0 >> 3) & 0b1 #0000x000
335 | #Activation status
336 | self.paramDic["gACT"]=gripperStatusReg0 & 0b00000001 #0000000x
337 |
338 | #########################################
339 | #Register 2001
340 | #First Byte: Fault status
341 | #Second Byte: Pos request echo
342 |
343 | #First Byte: fault status
344 | faultStatusReg2= (registers[1] >>8) & 0b11111111 #xxxxxxxx00000000
345 | #########################################
346 | #Universal controler
347 | self.paramDic["kFLT"]=(faultStatusReg2 >> 4) & 0b1111 #xxxx0000
348 | #Fault
349 | self.paramDic["gFLT"]=faultStatusReg2 & 0b00001111 #0000xxxx
350 |
351 |
352 | #########################################
353 | #Second Byte: Pos request echo
354 | posRequestEchoReg3=registers[1] & 0b11111111 #00000000xxxxxxxx
355 | #########################################
356 | #Echo of request position
357 | self.paramDic["gPR"]=posRequestEchoReg3
358 |
359 | #########################################
360 | #Register 2002
361 | #First Byte: Position
362 | #Second Byte: Current
363 |
364 | #First Byte: Position
365 | positionReg4=(registers[2] >> 8) & 0b11111111 #xxxxxxxx00000000
366 |
367 | #########################################
368 | #Actual position of the gripper
369 | self.paramDic["gPO"]=positionReg4
370 |
371 | #########################################
372 | #Second Byte: Current
373 | currentReg5=registers[2] & 0b0000000011111111 #00000000xxxxxxxx
374 | #########################################
375 | #Current
376 | self.paramDic["gCU"]=currentReg5
377 |
378 | def reset(self):
379 | """Reset the gripper (clear previous activation if any)
380 | """
381 | #Reset the gripper
382 | self.write_registers(1000,[0,0,0])
383 |
384 | def activate(self):
385 | """If not already activated, activate the gripper.
386 |
387 | .. warning::
388 | When you execute this function the gripper is going to fully open\
389 | and close. During this operation the gripper must be able to freely\
390 | move. Do not place object inside the gripper.
391 | """
392 | #Turn the variable which indicate that the gripper is processing
393 | #an action to True
394 | self.processing=True
395 |
396 | #Activate the gripper
397 | #rACT=1 Activate Gripper (must stay on after activation routine is
398 | #completed).
399 | self.write_registers(1000,[0b0000000100000000,0,0])
400 |
401 | #Waiting for activation to complete
402 | activationStartTime=time.time()
403 | activationCompleted=False
404 | activationTime=0
405 |
406 | while (not activationCompleted) and activationTime < self.timeOut:
407 | activationTime = time.time() - activationStartTime
408 |
409 | self.readAll()
410 | gSTA=self.paramDic["gSTA"]
411 |
412 | if gSTA==3:
413 | activationCompleted=True
414 | print("Activation completed. Activation time : "
415 | , activationTime)
416 | if activationTime > self.timeOut:
417 | raise Exception("Activation did not complete without timeout.")
418 |
419 | self.processing=False
420 |
421 | def resetActivate(self):
422 | """Reset the gripper (clear previous activation if any) and activat\
423 | the gripper. During this operation the gripper will open and close.
424 | """
425 | #Reset the gripper
426 | self.reset()
427 | #Activate the gripper
428 | self.activate()
429 |
430 | def goTo(self,position,speed=255,force=255):
431 | """Go to the position with determined speed and force.
432 |
433 | Args:
434 | - position (int): Position of the gripper. Integer between 0 and 255.\
435 | 0 being the open position and 255 being the close position.
436 | - speed (int): Gripper speed between 0 and 255
437 | - force (int): Gripper force between 0 and 255
438 |
439 | Returns:
440 | - objectDetected (bool): True if object detected
441 | - position (int): End position of the gripper in bits
442 | """
443 | position=int(position)
444 | speed=int(speed)
445 | force=int(force)
446 |
447 |
448 | #Check if the grippre is activated
449 | if self.isActivated == False:
450 | raise Exception ("Gripper must be activated before requesting\
451 | an action.")
452 |
453 | #Check input value
454 | if position>255:
455 | raise Exception("Position value cannot exceed 255")
456 | elif position<0:
457 | raise Exception("Position value cannot be under 0")
458 |
459 | self.processing=True
460 |
461 |
462 | #rARD(5) rATR(4) rGTO(3) rACT(0)
463 | #gACT=1 (Gripper activation.) and gGTO=1 (Go to Position Request.)
464 | self.write_registers(1000,[0b0000100100000000,
465 | position,
466 | speed * 0b100000000 + force])
467 |
468 | #Waiting for activation to complete
469 | motionStartTime=time.time()
470 | motionCompleted=False
471 | motionTime=0
472 | objectDetected=False
473 |
474 | while (not objectDetected) and (not motionCompleted)\
475 | and (motionTimeself.timeOut:
494 | raise Exception("Gripper never reach its requested position and\
495 | no object have been detected")
496 |
497 | position=self.paramDic["gPO"]
498 |
499 | return position, objectDetected
500 |
501 | def close(self,speed=255,force=255):
502 | """Close the gripper.
503 |
504 | Args:
505 | - speed (int, optional): Gripper speed between 0 and 255.\
506 | Default is 255.
507 | - force (int, optional): Gripper force between 0 and 255.\
508 | Default is 255.
509 | """
510 | self.goTo(255,speed,force)
511 |
512 | def open(self,speed=255,force=255):
513 | """Open the gripper
514 |
515 | Args:
516 | - speed (int, optional): Gripper speed between 0 and 255.\
517 | Default is 255.
518 | - force (int, optional): Gripper force between 0 and 255.\
519 | Default is 255.
520 | """
521 | self.goTo(0,force,speed)
522 |
523 | def goTomm(self,positionmm,speed=255,force=255):
524 | """Go to the requested opening expressed in mm
525 |
526 | Args:
527 | - positionmm (float): Gripper opening in mm.
528 | - speed (int, optional): Gripper speed between 0 and 255.\
529 | Default is 255.
530 | - force (int, optional): Gripper force between 0 and 255.\
531 | Default is 255.
532 |
533 | .. note::
534 | Calibration is needed to use this function.\n
535 | Execute the function calibrate at least 1 time before using this function.
536 | """
537 | if self.isCalibrated == False:
538 | raise Exception("The gripper must be calibrated before been requested to go to a position in mm")
539 |
540 | if positionmm>self.openmm:
541 | raise Exception("The maximum opening is {}".format(self.openmm))
542 |
543 | position=int(self._mmToBit(positionmm))
544 | self.goTo(position,speed,force)
545 |
546 | def getPosition(self):
547 | """Return the position of the gripper in bits
548 |
549 | Returns:
550 | - int: Position of the gripper in bits.
551 | """
552 | self.readAll()
553 |
554 | position=self.paramDic["gPO"]
555 |
556 | return position
557 |
558 | def _mmToBit(self,mm):
559 | """Convert a mm gripper opening in bit opening.
560 |
561 | .. note::
562 | Calibration is needed to use this function.\n
563 | Execute the function calibrate at least 1 time before using this function.
564 | """
565 | bit=(mm-self._bCoef)/self._aCoef
566 |
567 | return bit
568 |
569 | def _bitTomm(self,bit):
570 | """Convert a bit gripper opening in mm opening.
571 |
572 | Returns:
573 | float: Gripper position converted in mm
574 |
575 | .. note::
576 | Calibration is needed to use this function.\n
577 | Execute the function calibrate at least 1 time before using this function.
578 | """
579 | mm=self._aCoef*bit+self._bCoef
580 |
581 | return mm
582 |
583 | def getPositionmm(self):
584 | """Return the position of the gripper in mm.
585 |
586 | Returns:
587 | float: Current gripper position in mm
588 |
589 | .. note::
590 | Calibration is needed to use this function.\n
591 | Execute the function calibrate at least 1 time before using this function.
592 | """
593 | position=self.getPosition()
594 |
595 | positionmm=self._bitTomm(position)
596 | return positionmm
597 |
598 | def calibrate(self,closemm,openmm):
599 | """Calibrate the gripper for mm positionning.
600 |
601 | Once the calibration is done it is possible to control the gripper in\
602 | mm.
603 |
604 | Args:
605 | - closemm (float): Distance between the fingers when the gripper is\
606 | fully closed.
607 | - openmm (float): Distance between the fingers when the gripper is\
608 | fully open.
609 | """
610 | self.closemm=closemm
611 | self.openmm=openmm
612 |
613 | self.openGripper()
614 | #get open bit
615 | self.openbit=self.getPosition()
616 | obit=self.openbit
617 |
618 | self.closeGripper()
619 | #get close bit
620 | self.closebit=self.getPosition()
621 | cbit=self.closebit
622 |
623 | self._aCoef=(closemm-openmm)/(cbit-obit)
624 | self._bCoef=(openmm*cbit-obit*closemm)/(cbit-obit)
625 |
626 | def printInfo(self):
627 | """Print gripper register info in the python terminal
628 | """
629 | self.readAll()
630 | for key,value in self.paramDic.items():
631 | print("{} : {}".format(key,value))
632 | print(self.registerDic[key][value])
633 |
634 | def isActivated(self):
635 | """Tells if the gripper is activated
636 |
637 | Returns:
638 | bool: True if the gripper is activated. False otherwise.
639 | """
640 |
641 | self.readAll()
642 | is_activated = (self.paramDic["gSTA"]==3)
643 |
644 | return is_activated
645 |
646 | def isCalibrated(self):
647 | """Return if the gripper is qualibrated
648 |
649 | Returns:
650 | bool: True if the gripper is calibrated. False otherwise.
651 | """
652 | is_calibrated = False
653 | if (self.openmm is None) or (self.closemm is None):
654 | is_calibrated = False
655 | else:
656 | is_calibrated=True
657 |
658 | return is_calibrated
659 |
660 | #Test
661 | if False:
662 | grip=RobotiqGripper()
663 | grip.resetActivate()
664 | #grip.reset()
665 | #grip.goTo(0)
666 | #grip.goTo(255)
667 | #grip.printInfo()
668 | #grip.goTo(255)
669 | #time.sleep(5)
670 | #grip.printInfo()
671 | #grip.activate()
672 | #grip.printInfo()
673 |
674 | #grip.goTo(20)
675 | #grip.goTo(230)
676 | #grip.goTo(40)
677 | #grip.goTo(80)
678 |
679 | #grip.calibrate(0,36)
680 | #grip.goTomm(10,255,255)
681 | #grip.goTomm(40,1,255)
682 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["hatchling"]
3 | build-backend = "hatchling.build"
4 |
5 | [project]
6 | name = "pyRobotiqGripper"
7 | version = "1.0.0"
8 | authors = [
9 | { name="Benoit CASTETS", email="opensourceeng@gmail.com" },
10 | ]
11 | description = "Python Driver for Robotiq Grippers via Modbus RTU"
12 | readme = "README.md"
13 | requires-python = ">=3.8"
14 | classifiers = [
15 | "Programming Language :: Python :: 3",
16 | "License :: OSI Approved :: MIT License",
17 | "Operating System :: OS Independent",
18 | ]
19 |
20 | [project.urls]
21 | Homepage = "https://github.com/castetsb/pyRobotiqGripper"
22 | Issues = "https://github.com/castetsb/pyRobotiqGripper/issues"
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.12
3 | # by the following command:
4 | #
5 | # pip-compile setup.py
6 | #
7 | minimalmodbus==2.1.1
8 | # via pyRobotiqGripper (setup.py)
9 | pyserial==3.5
10 | # via minimalmodbus
11 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 | setup(
4 | name='pyRobotiqGripper',
5 | version='1.0.0',
6 | packages=find_packages(),
7 | install_requires=[
8 | 'minimalmodbus'
9 | ],
10 | author='Benoit CASTETS',
11 | author_email='opensourceeng@email.com',
12 | description='Python Driver for Robotiq Grippers via Modbus RTU',
13 | long_description=open('README.md').read(),
14 | long_description_content_type='text/markdown',
15 | url='https://github.com/castetsb/pyRobotiqGripper',
16 | classifiers=[
17 | 'Programming Language :: Python :: 3',
18 | # Add more classifiers as needed
19 | ],
20 | )
21 |
--------------------------------------------------------------------------------