Skip to content

Commit 7010f8f

Browse files
committed
new gripper
1 parent 4e75c0c commit 7010f8f

File tree

7 files changed

+115
-127
lines changed

7 files changed

+115
-127
lines changed

examples/swifty.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@
1414
# env.launch()
1515

1616
# Create a Panda robot object
17-
panda = rtb.models.ETS.Panda()
17+
panda = rtb.models.Panda()
1818

19-
print(panda)
20-
print(panda.base_link)
21-
print(panda.ee_links)
19+
# print(panda)
20+
# print(panda.base_link)
21+
# print(panda.ee_links)
2222

23-
path, n = panda.get_path(panda.base_link, panda.ee_links[0])
23+
# path, n = panda.get_path(panda.base_link, panda.ee_links[0])
2424

25-
q1 = np.array([1.4, 0.2, 1.8, 0.7, 0.1, 3.1, 2.9])
26-
panda.q = q1
25+
# q1 = np.array([1.4, 0.2, 1.8, 0.7, 0.1, 3.1, 2.9])
26+
# panda.q = q1
2727

28-
print(panda.fkine())
28+
# print(panda.fkine())
2929

30-
for link in path:
31-
print(link.name)
30+
# for link in path:
31+
# print(link.name)
3232

3333
# print(panda.get_path(panda.base_link, panda.ee_links[0])[0])
3434

roboticstoolbox/models/URDF/Panda.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ def __init__(self):
3838
elinks,
3939
name=name,
4040
manufacturer='Franka Emika',
41-
ee_links=elinks[8]
41+
ee_links=elinks[7],
42+
gripper_links=elinks[9]
4243
)
4344

4445
self.qdlim = np.array([

roboticstoolbox/robot/DHRobot.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from roboticstoolbox.robot.DHDynamics import DHDynamics
2020
from ansitable import ANSITable, Column
2121

22+
2223
class DHRobot(Robot, DHDynamics):
2324
"""
2425
Class for robots defined using Denavit-Hartenberg notation
@@ -468,8 +469,8 @@ def A(self, j, q=None):
468469
:return T: The transform between link frames
469470
:rtype T: SE3
470471
471-
- ``robot.A(j, q)`` transform between link frames {0} and {n}. ``q``
472-
is a vector (n) of joint variables.
472+
- ``robot.A(j, q)`` transform between link frames {0} and {n}. ``q``
473+
is a vector (n) of joint variables.
473474
- ``robot.A([j1, j2], q)`` as above between link frames {j1} and {j2}.
474475
- ``robot.A(j)`` as above except uses the stored q value of the
475476
robot object.
@@ -506,7 +507,7 @@ def islimit(self, q=None):
506507
:param q: The joint configuration of the robot (Optional,
507508
if not supplied will use the stored q values)
508509
:type q: ndarray(n
509-
:return v: is a vector of boolean values, one per joint, False if
510+
:return v: is a vector of boolean values, one per joint, False if
510511
``q[j]`` is within the joint limits, else True
511512
:rtype v: bool list
512513
@@ -526,16 +527,16 @@ def islimit(self, q=None):
526527
527528
"""
528529
q = self._getq(q)
529-
530+
530531
return [link.islimit(qk) for (link, qk) in zip(self, q)]
531532

532533
def isspherical(self):
533534
"""
534535
Test for spherical wrist
535-
536+
536537
:return: True if spherical wrist
537538
:rtype: bool
538-
539+
539540
Tests if the robot has a spherical wrist, that is, the last 3 axes are
540541
revolute and their axes intersect at a point.
541542
@@ -553,17 +554,17 @@ def isspherical(self):
553554

554555
alpha = [-np.pi / 2, np.pi / 2]
555556

556-
return L[0].a == 0 \
557-
and L[1].a == 0 \
558-
and L[1].d == 0 \
559-
and (
560-
(L[0].alpha == alpha[0] and L[1].alpha == alpha[1])
561-
or
562-
(L[0].alpha == alpha[1] and L[1].alpha == alpha[0])
563-
) \
564-
and L[0].sigma == 0 \
565-
and L[1].sigma == 0 \
566-
and L[2].sigma == 0
557+
return L[0].a == 0 \
558+
and L[1].a == 0 \
559+
and L[1].d == 0 \
560+
and (
561+
(L[0].alpha == alpha[0] and L[1].alpha == alpha[1])
562+
or
563+
(L[0].alpha == alpha[1] and L[1].alpha == alpha[0])
564+
) \
565+
and L[0].sigma == 0 \
566+
and L[1].sigma == 0 \
567+
and L[2].sigma == 0
567568

568569
def isprismatic(self):
569570
"""
@@ -669,9 +670,10 @@ def todegrees(self, q=None):
669670
q = self._getq(q)
670671
revolute = self.isrevolute()
671672

672-
return np.array(
673-
[q[k] * 180.0 / np.pi if revolute[k] else q[k] for k in range(len(q))]
674-
)
673+
return np.array([
674+
q[k] * 180.0 / np.pi if
675+
revolute[k] else q[k] for k in range(len(q))
676+
])
675677

676678
def toradians(self, q):
677679
"""

roboticstoolbox/robot/ERobot.py

Lines changed: 54 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from roboticstoolbox.backend import xacro
1818
from roboticstoolbox.backend import URDF
1919
from roboticstoolbox.robot.Robot import Robot
20+
from roboticstoolbox.robot.Gripper import Gripper
2021
from pathlib import PurePath, PurePosixPath
2122
from ansitable import ANSITable, Column
2223

@@ -52,15 +53,13 @@ def __init__(
5253
self,
5354
elinks,
5455
base_link=None,
55-
ee_links=None,
56+
gripper_links=None,
5657
**kwargs
5758
):
5859

5960
self._ets = []
6061
self._linkdict = {}
6162
self._n = 0
62-
# self._M = 0
63-
# self._q_idx = []
6463
self._ee_links = []
6564
self._base_link = None
6665

@@ -101,8 +100,7 @@ def __init__(
101100

102101
self._n = n
103102

104-
# scan for base and ee links
105-
ee = []
103+
# scan for base
106104
for link in elinks:
107105
# is this a base link?
108106
if link._parent is None:
@@ -113,18 +111,39 @@ def __init__(
113111
# no, update children of this link's parent
114112
link._parent._child.append(link)
115113

116-
for link in elinks:
117-
# is this a leaf node?
118-
if ee_links is None and len(link.child) == 0:
119-
# no children, must be an end-effector
120-
ee.append(link)
121-
122-
if ee_links is not None:
123-
# use the passed in value
124-
self.ee_links = ee_links
114+
# Set up the gripper, make a list containing the root of all
115+
# grippers
116+
if gripper_links is not None:
117+
if isinstance(gripper_links, ELink):
118+
gripper_links = [gripper_links]
125119
else:
126-
# use the leaf links
127-
self.ee_links = ee
120+
gripper_links = []
121+
122+
# An empty list to hold all grippers
123+
self.grippers = []
124+
125+
# Make a gripper object for each gripper
126+
for link in gripper_links:
127+
g_links = self.dfs_links(link)
128+
self.grippers.append(Gripper(g_links))
129+
130+
# Subtract the n of the grippers from the n of the robot
131+
for gripper in self.grippers:
132+
self._n -= gripper.n
133+
134+
# Set the ee links
135+
self.ee_links = []
136+
if gripper_links is None:
137+
for link in elinks:
138+
# is this a leaf node? and do we not have any grippers
139+
if len(link.child) == 0:
140+
# no children, must be an end-effector
141+
self.ee_links.append(link)
142+
# else:
143+
# for link = self.gripper_links:
144+
# # use the passed in value
145+
# self.ee_links.append(link.)
146+
128147

129148
# assign the joint indices
130149
if all([link.jindex is None for link in elinks]):
@@ -141,12 +160,9 @@ def visit_link(link, jindex):
141160
link.jindex = jindex[0]
142161
jindex[0] += 1
143162

144-
# visit all links in BFS order
145-
self.bfs_link(
163+
# visit all links in DFS order
164+
self.dfs_links(
146165
self.base_link, lambda link: visit_link(link, jindex))
147-
# self._n = len(self._q_idx)
148-
149-
self._reset_fk_path()
150166

151167
elif all([link.jindex is not None for link in elinks]):
152168
# jindex set on all, check they are unique and sequential
@@ -163,49 +179,6 @@ def visit_link(link, jindex):
163179
# must be a mixture of ELinks with/without jindex
164180
raise ValueError('all links must have a jindex, or none have a jindex')
165181

166-
167-
# # Set up references between links, a bi-directional linked list
168-
# # Also find the top of the tree
169-
# self.end = []
170-
# for link in elinks:
171-
# if link.parent is None:
172-
# self.root = link
173-
# else:
174-
# link.parent._child.append(link)
175-
176-
# # Find the bottom of the tree
177-
# for link in elinks:
178-
# if len(link.child) == 0:
179-
# self.end.append(link)
180-
181-
# # If the base link is not defined, use the root of the tree
182-
# if base_link is None:
183-
# self._base_link = self.root # Needs to be private attrib
184-
# else:
185-
# self._base_link = base_link # Needs to be private attrib
186-
187-
# # If the ee link is not defined, use the bottom of the tree
188-
# if ee_link is None:
189-
# self._ee_link = self.end[-1]
190-
# else:
191-
# self._ee_link = [ee_link]
192-
193-
# scan for the base and ee links
194-
# assign joint variables
195-
# def add_links(link, lst, q_idx):
196-
197-
# if link.isjoint:
198-
# q_idx.append(len(lst))
199-
200-
# lst.append(link)
201-
202-
# Figure out the order of links with respect to joint variables
203-
# self.bfs_link(
204-
# lambda link: add_links(link, self._ets, self._q_idx))
205-
# self._n = len(self._q_idx)
206-
207-
# self._reset_fk_path()
208-
209182
# Current joint angles of the robot
210183
# TODO should go to Robot class?
211184
self.q = np.zeros(self.n)
@@ -215,45 +188,34 @@ def visit_link(link, jindex):
215188

216189
super().__init__(elinks, **kwargs)
217190

218-
def _reset_fk_path(self):
219-
# Pre-calculate the forward kinematics path
220-
self._fkpath = self.dfs_path(self.base_link, self.ee_links)
221-
222-
# def bfs_link(self, func):
223-
# queue = self.root
224-
225-
# for li in queue:
226-
# func(li)
227-
228-
# def vis_children(link):
229-
# for li in link.child:
230-
# if li not in queue:
231-
# queue.append(li)
232-
# func(li)
233-
234-
# while len(queue) > 0:
235-
# link = queue.pop(0)
236-
# vis_children(link)
237-
238-
def bfs_link(self, start, func):
191+
def dfs_links(self, start, func=None):
239192
"""
240-
Visit each link in BFS order
193+
Visit all links from start in depth-first order and will apply
194+
func to each visited link
195+
196+
:param start: the link to start at
197+
:type start: ELink
198+
:param func: An optional function to apply to each link as it is found
199+
:type func: function
241200
242-
:param func: [description]
243-
:type func: [type]
201+
:returns: A list of links
202+
:rtype: list of ELink
244203
"""
245-
visited = [start]
204+
visited = []
246205

247206
def vis_children(link):
248207
visited.append(link)
249-
func(link)
208+
if func is not None:
209+
func(link)
250210

251211
for li in link.child:
252212
if li not in visited:
253213
vis_children(li)
254214

255215
vis_children(start)
256216

217+
return visited
218+
257219
def dfs_path(self, l1, l2):
258220
path = []
259221
visited = [l1]
@@ -475,7 +437,7 @@ def base_link(self, link):
475437
else:
476438
# self._base_link = self.links[link]
477439
raise ValueError('must be an ELink')
478-
self._reset_fk_path()
440+
# self._reset_fk_path()
479441
# --------------------------------------------------------------------- #
480442

481443
@property
@@ -498,7 +460,7 @@ def ee_links(self, link):
498460
self._ee_links = link
499461
else:
500462
raise ValueError('expecting an ELink or list of ELinks')
501-
self._reset_fk_path()
463+
# self._reset_fk_path()
502464
# --------------------------------------------------------------------- #
503465

504466
# @property

roboticstoolbox/robot/Gripper.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python
2+
"""
3+
@author Jesse Haviland
4+
"""
5+
6+
7+
class Gripper():
8+
9+
def __init__(
10+
self,
11+
elinks
12+
):
13+
14+
self._n = 0
15+
16+
for link in elinks:
17+
if link.isjoint:
18+
self._n += 1
19+
20+
@property
21+
def n(self):
22+
return self._n

0 commit comments

Comments
 (0)