Skip to content

Commit 725ba24

Browse files
author
David Butterworth
committed
Add GetLinearCollisionCheckPts() to generate sequence of points to be collision-checked, for piece-wise linear trajectories.
1 parent 5459f35 commit 725ba24

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

src/prpy/util.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,135 @@ def GetCollisionCheckPts(robot, traj, include_start=True, start_time=0.,
11871187
dt = 2. * dt
11881188

11891189

1190+
def GetLinearCollisionCheckPts(robot, traj, norm_order=2, sampling_order=None):
1191+
"""
1192+
For a piece-wise linear trajectory, generate a list
1193+
of configuration pairs that need to be collision checked.
1194+
1195+
This will step along the trajectory from start to end
1196+
at a resolution that satisifies the specified error metric.
1197+
1198+
@param openravepy.Robot robot: The robot.
1199+
@param openravepy.Trajectory traj: The trajectory for which we need
1200+
to generate sample points.
1201+
@param int norm_order: 1 ==> The L1 norm
1202+
2 ==> The L2 norm
1203+
inf ==> The L_infinity norm
1204+
@param string sampling_order:
1205+
'linear' : Sample in a linear sequence
1206+
'van_der_corput' : Sample in an optimal sequence
1207+
1208+
@returns generator: A tuple (t,q) of float values, being the sample
1209+
time and joint configuration.
1210+
"""
1211+
1212+
# If trajectory is already timed, strip the deltatime values
1213+
if IsTimedTrajectory(traj):
1214+
traj = UntimeTrajectory(traj)
1215+
1216+
traj_cspec = traj.GetConfigurationSpecification()
1217+
1218+
# Make sure trajectory is linear in joint space
1219+
try:
1220+
# type can be 'linear' or 'quadratic'
1221+
interp_type = traj_cspec.GetGroupFromName('joint_values').interpolation
1222+
except openravepy.openrave_exception:
1223+
raise ValueError('Failed calling GetGroupFromName()')
1224+
if interp_type != 'linear':
1225+
raise ValueError('Trajectory must be linear in joint space')
1226+
1227+
dof_indices, _ = traj_cspec.ExtractUsedIndices(robot)
1228+
1229+
# If trajectory only has 1 waypoint then we only need to
1230+
# do 1 collision check.
1231+
num_waypoints = traj.GetNumWaypoints()
1232+
if num_waypoints == 1:
1233+
t = 0.0
1234+
waypoint = traj.GetWaypoint(0)
1235+
q = traj_cspec.ExtractJointValues(waypoint, robot, dof_indices)
1236+
yield t, q
1237+
return
1238+
1239+
env = robot.GetEnv()
1240+
1241+
# Create a temporary trajectory that we will use
1242+
# for sampling the points to collision check,
1243+
# because there is no method to modify the 'deltatime'
1244+
# values of waypoints in an OpenRAVE trajectory.
1245+
temp_traj_cspec = traj.GetConfigurationSpecification()
1246+
temp_traj_cspec.AddDeltaTimeGroup()
1247+
temp_traj = openravepy.RaveCreateTrajectory(env, '')
1248+
temp_traj.Init(temp_traj_cspec)
1249+
1250+
# Set timing of first waypoint in temporary trajectory to t=0
1251+
waypoint = traj.GetWaypoint(0, temp_traj_cspec)
1252+
q0 = traj_cspec.ExtractJointValues(waypoint, robot, dof_indices)
1253+
delta_time = 0.0
1254+
temp_traj_cspec.InsertDeltaTime(waypoint, delta_time)
1255+
temp_traj.Insert(0, waypoint)
1256+
1257+
# Get the resolution (in radians) for each joint
1258+
q_resolutions = robot.GetDOFResolutions()[dof_indices]
1259+
1260+
# Iterate over each segment in the trajectory and set
1261+
# the timing of each waypoint in the temporary trajectory
1262+
# so that taking steps of t=1 will be within a required error norm.
1263+
for i in range(1, num_waypoints):
1264+
# We already have the first waypoint (q0) of this segment,
1265+
# so get the joint values for the second waypoint.
1266+
waypoint = traj.GetWaypoint(i)
1267+
q1 = traj_cspec.ExtractJointValues(waypoint, robot, dof_indices)
1268+
dq = numpy.abs(q1 - q0)
1269+
max_diff_float = numpy.max( numpy.abs(q1 - q0) / q_resolutions)
1270+
1271+
# Get the number of steps (as a float) required for
1272+
# each joint at DOF resolution
1273+
num_steps = dq / q_resolutions
1274+
1275+
# Calculate the norm:
1276+
#
1277+
# norm_order = 1 ==> The L1 norm
1278+
# Which is like a diamond shape in configuration space
1279+
# and equivalent to: L1_norm=sum(num_steps)
1280+
#
1281+
# norm_order = 2 ==> The L2 norm
1282+
# Which is like an ellipse in configuration space
1283+
# and equivalent to: L2_norm=numpy.linalg.norm(num_steps)
1284+
#
1285+
# norm_order = inf ==> The L_infinity norm
1286+
# Which is like a box shape in configuration space
1287+
# and equivalent to: L_inf_norm=numpy.max(num_steps)
1288+
norm = numpy.linalg.norm(num_steps, ord=norm_order)
1289+
1290+
# Set timing of this waypoint
1291+
waypoint = traj.GetWaypoint(i, temp_traj_cspec)
1292+
delta_time = norm
1293+
temp_traj_cspec.InsertDeltaTime(waypoint, delta_time)
1294+
temp_traj.Insert(i, waypoint)
1295+
1296+
# The last waypoint becomes the first in the next segment
1297+
q0 = q1
1298+
1299+
traj_duration = temp_traj.GetDuration()
1300+
1301+
# Sample the trajectory using the specified sequence
1302+
seq = None
1303+
if sampling_order == 'van_der_corput':
1304+
# An approximate Van der Corput sequence, between the
1305+
# start and end points
1306+
seq = VanDerCorputSampleGenerator(0, traj_duration, step=2)
1307+
else: # sampling_order='linear'
1308+
# (default) Linear sequence, from start to end
1309+
seq = SampleTimeGenerator(0, traj_duration, step=2)
1310+
1311+
# Sample the trajectory in time
1312+
# and return time value and joint positions
1313+
for t in seq:
1314+
sample = temp_traj.Sample(t)
1315+
q = temp_traj_cspec.ExtractJointValues(sample, robot, dof_indices)
1316+
yield t, q
1317+
1318+
11901319
def IsInCollision(traj, robot, selfcoll_only=False):
11911320
report = openravepy.CollisionReport()
11921321

0 commit comments

Comments
 (0)