Skip to content

Commit 84298b5

Browse files
committed
switched p_servo to angle-axis method
1 parent 0066949 commit 84298b5

File tree

1 file changed

+82
-59
lines changed

1 file changed

+82
-59
lines changed

roboticstoolbox/tools/p_servo.py

Lines changed: 82 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5,76 +5,99 @@
55
import math
66

77

8-
def p_servo(wTe, wTep, gain=2, threshold=0.1):
9-
"""
10-
Position-based servoing.
11-
12-
Returns the end-effector velocity which will cause the robot to approach
13-
the desired pose.
14-
15-
:param wTe: The current pose of the end-effecor in the base frame.
16-
:type wTe: SE3
17-
:param wTep: The desired pose of the end-effecor in the base frame.
18-
:type wTep: SE3
19-
:param gain: The gain for the controller
20-
:type gain: float
21-
:param threshold: The threshold or tolerance of the final error between
22-
the robot's pose and desired pose
23-
:type threshold: float
24-
25-
:returns v: The velocity of the end-effecotr which will casue the robot
26-
to approach wTep
27-
:rtype v: ndarray(6)
28-
:returns arrived: True if the robot is within the threshold of the final
29-
pose
30-
:rtype arrived: bool
31-
32-
"""
8+
# def p_servo(wTe, wTep, gain=2, threshold=0.1):
9+
# """
10+
# Position-based servoing.
3311

34-
if not isinstance(wTe, SE3):
35-
wTe = SE3(wTe)
12+
# Returns the end-effector velocity which will cause the robot to approach
13+
# the desired pose.
3614

37-
if not isinstance(wTep, SE3):
38-
wTep = SE3(wTep)
15+
# :param wTe: The current pose of the end-effecor in the base frame.
16+
# :type wTe: SE3
17+
# :param wTep: The desired pose of the end-effecor in the base frame.
18+
# :type wTep: SE3
19+
# :param gain: The gain for the controller
20+
# :type gain: float
21+
# :param threshold: The threshold or tolerance of the final error between
22+
# the robot's pose and desired pose
23+
# :type threshold: float
3924

40-
# Pose difference
41-
eTep = wTe.inv() * wTep
25+
# :returns v: The velocity of the end-effecotr which will casue the robot
26+
# to approach wTep
27+
# :rtype v: ndarray(6)
28+
# :returns arrived: True if the robot is within the threshold of the final
29+
# pose
30+
# :rtype arrived: bool
4231

43-
# Translational error
44-
ev = eTep.t
32+
# """
4533

46-
# Angular error
47-
ew = eTep.rpy("rad")
34+
# if not isinstance(wTe, SE3):
35+
# wTe = SE3(wTe)
4836

49-
# Form error vector
50-
e = np.r_[ev, ew]
37+
# if not isinstance(wTep, SE3):
38+
# wTep = SE3(wTep)
5139

52-
# Desired end-effector velocity
53-
v = gain * e
40+
# # Pose difference
41+
# eTep = wTe.inv() * wTep
5442

55-
if np.sum(np.abs(e)) < threshold:
56-
arrived = True
57-
else:
58-
arrived = False
43+
# # Translational error
44+
# ev = eTep.t
5945

60-
return v, arrived
46+
# # Angular error
47+
# ew = eTep.rpy("rad")
6148

49+
# # Form error vector
50+
# e = np.r_[ev, ew]
6251

63-
# def _angle_axis(T, Td):
64-
# d = base.transl(Td) - base.transl(T)
65-
# R = base.t2r(Td) @ base.t2r(T).T
66-
# li = np.r_[R[2, 1] - R[1, 2], R[0, 2] - R[2, 0], R[1, 0] - R[0, 1]]
52+
# # Desired end-effector velocity
53+
# v = gain * e
6754

68-
# if base.iszerovec(li):
69-
# # diagonal matrix case
70-
# if np.trace(R) > 0:
71-
# # (1,1,1) case
72-
# a = np.zeros((3,))
73-
# else:
74-
# a = np.pi / 2 * (np.diag(R) + 1)
55+
# if np.sum(np.abs(e)) < threshold:
56+
# arrived = True
7557
# else:
76-
# # non-diagonal matrix case
77-
# ln = base.norm(li)
78-
# a = math.atan2(ln, np.trace(R) - 1) * li / ln
58+
# arrived = False
59+
60+
# return v, arrived
61+
62+
63+
def _angle_axis(T, Td):
64+
e = np.zeros(6)
65+
e[:3] = Td.t - T.t
66+
R = Td.R @ T.R.T
67+
li = np.array([R[2, 1] - R[1, 2], R[0, 2] - R[2, 0], R[1, 0] - R[0, 1]])
68+
69+
if base.iszerovec(li):
70+
# diagonal matrix case
71+
if np.trace(R) > 0:
72+
# (1,1,1) case
73+
a = np.zeros((3,))
74+
else:
75+
a = np.pi / 2 * (np.diag(R) + 1)
76+
else:
77+
# non-diagonal matrix case
78+
ln = base.norm(li)
79+
a = math.atan2(ln, np.trace(R) - 1) * li / ln
80+
81+
e[3:] = a
82+
83+
return e
7984

80-
# return np.r_[d, a]
85+
86+
def p_servo(wTe, wTep, gain=[1.0, 1.0, 1.0, 1.0, 1.0, 1.0], threshold=0.1):
87+
if not isinstance(wTe, SE3):
88+
wTe = SE3(wTe)
89+
90+
if not isinstance(wTep, SE3):
91+
wTep = SE3(wTep)
92+
93+
k = np.diag(gain)
94+
95+
e = _angle_axis(wTe, wTep)
96+
97+
v = k @ e
98+
99+
arrived = True if np.sum(np.abs(e)) < threshold else False
100+
101+
print(np.sum(np.abs(e)))
102+
103+
return v, arrived

0 commit comments

Comments
 (0)