Skip to content

Commit d5c9988

Browse files
committed
add minjerk interpolation method
1 parent bc76d5e commit d5c9988

File tree

3 files changed

+347
-15
lines changed

3 files changed

+347
-15
lines changed

scripts/joint_trajectory_action_server.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
)
5353

5454

55-
def start_server(limb, rate, mode):
55+
def start_server(limb, rate, mode, interpolation):
5656
print("Initializing node... ")
5757
rospy.init_node("rsdk_%s_joint_trajectory_action_server%s" %
5858
(mode, "" if limb == 'both' else "_" + limb,))
@@ -70,11 +70,11 @@ def start_server(limb, rate, mode):
7070
jtas = []
7171
if limb == 'both':
7272
jtas.append(JointTrajectoryActionServer('right', dyn_cfg_srv,
73-
rate, mode))
73+
rate, mode, interpolation))
7474
jtas.append(JointTrajectoryActionServer('left', dyn_cfg_srv,
75-
rate, mode))
75+
rate, mode, interpolation))
7676
else:
77-
jtas.append(JointTrajectoryActionServer(limb, dyn_cfg_srv, rate, mode))
77+
jtas.append(JointTrajectoryActionServer(limb, dyn_cfg_srv, rate, mode, interpolation))
7878

7979
def cleanup():
8080
for j in jtas:
@@ -102,8 +102,13 @@ def main():
102102
choices=['position_w_id', 'position', 'velocity'],
103103
help="control mode for trajectory execution"
104104
)
105+
parser.add_argument(
106+
"-i", "--interpolation", default='bezier',
107+
choices=['bezier', 'minjerk'],
108+
help="interpolation method for trajectory generation"
109+
)
105110
args = parser.parse_args(rospy.myargv()[1:])
106-
start_server(args.limb, args.rate, args.mode)
111+
start_server(args.limb, args.rate, args.mode, args.interpolation)
107112

108113

109114
if __name__ == "__main__":

src/joint_trajectory_action/joint_trajectory_action.py

+67-10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import numpy as np
3636

3737
import bezier
38+
import minjerk
3839

3940
import rospy
4041

@@ -59,7 +60,7 @@
5960

6061
class JointTrajectoryActionServer(object):
6162
def __init__(self, limb, reconfig_server, rate=100.0,
62-
mode='position_w_id'):
63+
mode='position_w_id', interpolation='bezier'):
6364
self._dyn = reconfig_server
6465
self._ns = 'robot/limb/' + limb
6566
self._fjt_ns = self._ns + '/follow_joint_trajectory'
@@ -72,6 +73,7 @@ def __init__(self, limb, reconfig_server, rate=100.0,
7273
self._limb = baxter_interface.Limb(limb)
7374
self._enable = baxter_interface.RobotEnable()
7475
self._name = limb
76+
self._interpolation = interpolation
7577
self._cuff = baxter_interface.DigitalIO('%s_lower_cuff' % (limb,))
7678
self._cuff.state_changed.connect(self._cuff_cb)
7779
# Verify joint control mode
@@ -332,6 +334,47 @@ def _compute_bezier_coeff(self, joint_names, trajectory_points, dimensions_dict)
332334
b_matrix[jnt, :, :, :] = bezier.bezier_coefficients(traj_array, d_pts)
333335
return b_matrix
334336

337+
def _get_minjerk_point(self, m_matrix, idx, t, cmd_time, dimensions_dict):
338+
pnt = JointTrajectoryPoint()
339+
pnt.time_from_start = rospy.Duration(cmd_time)
340+
num_joints = m_matrix.shape[0]
341+
pnt.positions = [0.0] * num_joints
342+
if dimensions_dict['velocities']:
343+
pnt.velocities = [0.0] * num_joints
344+
if dimensions_dict['accelerations']:
345+
pnt.accelerations = [0.0] * num_joints
346+
for jnt in range(num_joints):
347+
m_point = minjerk.minjerk_point(m_matrix[jnt, :, :, :], idx, t)
348+
# Positions at specified time
349+
pnt.positions[jnt] = m_point[0]
350+
# Velocities at specified time
351+
if dimensions_dict['velocities']:
352+
pnt.velocities[jnt] = m_point[1]
353+
# Accelerations at specified time
354+
if dimensions_dict['accelerations']:
355+
pnt.accelerations[jnt] = m_point[-1]
356+
return pnt
357+
358+
def _compute_minjerk_coeff(self, joint_names, trajectory_points, point_duration, dimensions_dict):
359+
# Compute Full Minimum Jerk Curve
360+
num_joints = len(joint_names)
361+
num_traj_pts = len(trajectory_points)
362+
num_traj_dim = sum(dimensions_dict.values())
363+
num_m_values = len(['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'tm'])
364+
m_matrix = np.zeros(shape=(num_joints, num_traj_dim, num_traj_pts-1, num_m_values))
365+
for jnt in xrange(num_joints):
366+
traj_array = np.zeros(shape=(len(trajectory_points), num_traj_dim))
367+
for idx, point in enumerate(trajectory_points):
368+
current_point = list()
369+
current_point.append(point.positions[jnt])
370+
if dimensions_dict['velocities']:
371+
current_point.append(point.velocities[jnt])
372+
if dimensions_dict['accelerations']:
373+
current_point.append(point.accelerations[jnt])
374+
traj_array[idx, :] = current_point
375+
m_matrix[jnt, :, :, :] = minjerk.minjerk_coefficients(traj_array, point_duration)
376+
return m_matrix
377+
335378
def _determine_dimensions(self, trajectory_points):
336379
# Determine dimensions supplied
337380
position_flag = True
@@ -385,15 +428,24 @@ def _on_trajectory_action(self, goal):
385428
if dimensions_dict['accelerations']:
386429
trajectory_points[-1].accelerations = [0.0] * len(joint_names)
387430

388-
# Compute Full Bezier Curve Coefficients for all 7 joints
389431
pnt_times = [pnt.time_from_start.to_sec() for pnt in trajectory_points]
390432
try:
391-
b_matrix = self._compute_bezier_coeff(joint_names,
392-
trajectory_points,
393-
dimensions_dict)
433+
if self._interpolation == 'minjerk':
434+
# Compute Full MinJerk Curve Coefficients for all 7 joints
435+
point_duration = [pnt_times[i+1] - pnt_times[i] for i in range(len(pnt_times)-1)]
436+
m_matrix = self._compute_minjerk_coeff(joint_names,
437+
trajectory_points,
438+
point_duration,
439+
dimensions_dict)
440+
else:
441+
# Compute Full Bezier Curve Coefficients for all 7 joints
442+
b_matrix = self._compute_bezier_coeff(joint_names,
443+
trajectory_points,
444+
dimensions_dict)
394445
except Exception as ex:
395-
rospy.logerr(("{0}: Failed to compute a Bezier trajectory for {1}"
396-
" arm with error \"{2}: {3}\"").format(
446+
rospy.logerr(("{0}: Failed to compute a {1} trajectory for {2}"
447+
" arm with error \"{3}: {4}\"").format(
448+
self._interpolation,
397449
self._action_name,
398450
self._name,
399451
type(ex).__name__, ex))
@@ -429,9 +481,14 @@ def _on_trajectory_action(self, goal):
429481
cmd_time = 0
430482
t = 0
431483

432-
point = self._get_bezier_point(b_matrix, idx,
433-
t, cmd_time,
434-
dimensions_dict)
484+
if self._interpolation == 'minjerk':
485+
point = self._get_minjerk_point(m_matrix, idx,
486+
t, cmd_time,
487+
dimensions_dict)
488+
else:
489+
point = self._get_bezier_point(b_matrix, idx,
490+
t, cmd_time,
491+
dimensions_dict)
435492

436493
# Command Joint Position, Velocity, Acceleration
437494
command_executed = self._command_joints(joint_names, point, start_time, dimensions_dict)

0 commit comments

Comments
 (0)