-
Notifications
You must be signed in to change notification settings - Fork 463
/
mmc.py
99 lines (71 loc) · 2.46 KB
/
mmc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/env python
"""
@author Jesse Haviland
"""
import swift
import roboticstoolbox as rtb
import spatialmath as sm
import numpy as np
import qpsolvers as qp
"""
This is an implementation of the controller from:
J. Haviland and P. Corke, “A purely-reactive manipulability-maximising
motion controller,” arXiv preprint arXiv:2002.11901,2020.
"""
# Launch the simulator Swift
env = swift.Swift()
env.launch()
# Create a Panda robot object
panda = rtb.models.Panda()
# Set joint angles to ready configuration
panda.q = panda.qr
# Add the Panda to the simulator
env.add(panda)
# Number of joint in the panda which we are controlling
n = 7
# Set the desired end-effector pose
Tep = panda.fkine(panda.q) * sm.SE3(0.3, 0.2, 0.3)
arrived = False
while not arrived:
# The pose of the Panda's end-effector
Te = panda.fkine(panda.q)
# Transform from the end-effector to desired pose
eTep = Te.inv() * Tep
# Spatial error
e = np.sum(np.abs(np.r_[eTep.t, eTep.rpy() * np.pi / 180]))
# Calulate the required end-effector spatial velocity for the robot
# to approach the goal. Gain is set to 1.0
v, arrived = rtb.p_servo(Te, Tep, 1.0)
# Gain term (lambda) for control minimisation
Y = 0.01
# Quadratic component of objective function
Q = np.eye(n + 6)
# Joint velocity component of Q
Q[:n, :n] *= Y
# Slack component of Q
Q[n:, n:] = (1 / e) * np.eye(6)
# The equality contraints
Aeq = np.c_[panda.jacobe(panda.q), np.eye(6)]
beq = v.reshape((6,))
# The inequality constraints for joint limit avoidance
Ain = np.zeros((n + 6, n + 6))
bin = np.zeros(n + 6)
# The minimum angle (in radians) in which the joint is allowed to approach
# to its limit
ps = 0.05
# The influence angle (in radians) in which the velocity damper
# becomes active
pi = 0.9
# Form the joint limit velocity damper
Ain[:n, :n], bin[:n] = panda.joint_velocity_damper(ps, pi, n)
# Linear component of objective function: the manipulability Jacobian
c = np.r_[-panda.jacobm().reshape((n,)), np.zeros(6)]
# The lower and upper bounds on the joint velocity and slack variable
lb = -np.r_[panda.qdlim[:n], 10 * np.ones(6)]
ub = np.r_[panda.qdlim[:n], 10 * np.ones(6)]
# Solve for the joint velocities dq
qd = qp.solve_qp(Q, c, Ain, bin, Aeq, beq, lb=lb, ub=ub)
# Apply the joint velocities to the Panda
panda.qd[:n] = qd[:n]
# Step the simulator by 50 ms
env.step(0.05)