38 from moveit_msgs.msg
import RobotTrajectory, JointConstraint, Constraints, MotionPlanRequest,\
40 from moveit_msgs.srv
import GetMotionPlan, GetMotionPlanRequest, ApplyPlanningScene,\
41 ApplyPlanningSceneRequest
42 from trajectory_msgs.msg
import JointTrajectory
43 from threading
import RLock
44 from octomap_msgs.msg
import Octomap
45 import tf_conversions.posemath
as pm
49 This function converts dictionary of joint positions to moveit_msgs.Constraints structure. 51 @param q_map dictionary: A dictionary {name:position} of desired joint positions. 52 @param tolerance float: Tolerance of goal position. 53 @param group list of strings: Names of active joints in planning group. 54 Only constraints for these joints should be generated. 55 @return Returns filled moveit_msgs.Constraints structure. 57 result = Constraints()
58 for joint_name
in q_map:
59 if group !=
None and not joint_name
in group:
61 constraint = JointConstraint()
62 constraint.joint_name = joint_name
63 constraint.position = q_map[ joint_name ]
64 constraint.tolerance_above = tolerance
65 constraint.tolerance_below = tolerance
66 constraint.weight = 1.0
67 result.joint_constraints.append( constraint )
77 Class used for obtaining occupancy map (as octomap) from octomap server. 81 def _octomap_callback(self, data):
87 Initialization, ROS topic subscription. 89 @param topic string: octomap ROS topic. 97 Get current octomap from octomap server. 99 @param timeout_s float: Timeout in seconds. 101 @return Octomap object of type octomap_msgs.msg.Octomap, or None if timed out. 103 if timeout_s ==
None:
109 time_start = time.time()
110 while not rospy.is_shutdown():
115 time_now = time.time()
116 if timeout_s
and (time_now-time_start) > timeout_s:
121 return (angle + math.pi) % (2 * math.pi) - math.pi
125 assert isinstance(vec_E, PyKDL.Vector)
127 vec_E = copy.copy(vec_E)
129 print(
'keepUprightIk(): vec_E: {}'.format(
KDL2str(vec_E)))
130 if abs(vec_E.x()) < epsilon
and abs(vec_E.y()) < epsilon:
133 q0 =
wrapAngle( math.atan2(vec_E.y(), vec_E.x()) + math.pi/2 )
135 T_E_U1 = PyKDL.Frame( PyKDL.Rotation.RotZ(q0), PyKDL.Vector() )
137 vec_U1 = T_E_U1.M.Inverse() * vec_E
138 print(
'vec_U1: {}'.format(
KDL2str(vec_U1)))
139 if abs(vec_U1.y()) < epsilon
and abs(vec_U1.z()) < epsilon:
142 q1 =
wrapAngle( math.atan2(vec_U1.z(), vec_U1.y()) + math.pi/2 )
144 T_U1_U2 = PyKDL.Frame( PyKDL.Rotation.RotY(math.pi/2)*PyKDL.Rotation.RotZ(q1), PyKDL.Vector() )
145 T_E_U2 = T_E_U1 * T_U1_U2
147 vec_E_check = T_E_U2 * PyKDL.Vector(1,0,0)
148 if (vec_E - vec_E_check).Norm() > 0.001:
149 raise Exception(
'Check did not pass: {} != {}'.format(
KDL2str(vec_E),
KDL2str(vec_E_check)))
181 if isinstance(x, PyKDL.Vector):
182 return 'PyKDL.Vector({}, {}, {})'.format(x.x(), x.y(), x.z())
183 elif isinstance(x, PyKDL.Rotation):
184 q = x.GetQuaternion()
185 return 'PyKDL.Rotation.Quaternion({}, {}, {}, {})'.format(q[0], q[1], q[2], q[3])
186 elif isinstance(x, PyKDL.Frame):
189 raise Exception(
'Not supported argument: "{}"'.format(x))
193 Class used as planner interface. 195 def plan(self, q_start, goal_constraints, group_name, attached_collision_objects=None, is_diff=False,
196 path_constraints=None, trajectory_constraints=None, workspace_parameters=None,
197 planner_id=None, num_planning_attempts=1,
198 allowed_planning_time=10.0, max_velocity_scaling_factor=1.0,
199 max_acceleration_scaling_factor=1.0, keep_upright=None):
201 Plan motion in joint space. 203 @param q_start dictionary: A dictionary {name:position} of starting configuration. 204 @param goal_constraints list: A list of goal constraints of type moveit_msgs.msg.Constraints. 205 @param group_name string: Name of joint group to perform planning on. 206 @param attached_collision_objects list: Objects attached to robot represented as a list of objects 207 of type moveit_msgs.msg.AttachedCollisionObject. 209 @param path_constraints Path constraints of type moveit_msgs.msg.Constraints. 210 @param trajectory_constraints Trajectory constraints of type moveit_msgs.msg.TrajectoryConstraints. 211 @param workspace_parameters Parameters of robots workspace of type moveit_msgs.msg.WorkspaceParameters. 212 @param planner_id string: Name of planning algorithm. 213 @param num_planning_attempts int: Maximum number of planning attempts. 214 @param allowed_planning_time float: Maximum allowed time for planning. 215 @param max_velocity_scaling_factor float: Scaling factor for velocity: the bigger, the faster robot moves. 216 @param max_acceleration_scaling_factor float: Scaling factor for acceleration: the bigger, the faster robot accelerates. 218 @return Returns trajectory_msgs.msg.JointTrajectory. 220 req = MotionPlanRequest()
222 q_start = copy.copy(q_start)
223 if not 'leftKeepUprightJoint0' in q_start:
224 q_start[
'leftKeepUprightJoint0'] = 0.0
225 if not 'leftKeepUprightJoint1' in q_start:
226 q_start[
'leftKeepUprightJoint1'] = 0.0
227 if not 'rightKeepUprightJoint0' in q_start:
228 q_start[
'rightKeepUprightJoint0'] = 0.0
229 if not 'rightKeepUprightJoint1' in q_start:
230 q_start[
'rightKeepUprightJoint1'] = 0.0
232 for joint_name
in sorted(q_start.keys()):
233 req.start_state.joint_state.name.append( joint_name )
234 req.start_state.joint_state.position.append( q_start[joint_name] )
236 if attached_collision_objects:
237 print(
'Planner.plan(): there are some objects attached to grippers')
238 req.start_state.attached_collision_objects = attached_collision_objects
240 req.start_state.is_diff = is_diff
242 req.goal_constraints = goal_constraints
244 req.group_name = group_name
247 req.path_constraints = path_constraints
249 if trajectory_constraints:
250 req.trajectory_constraints = trajectory_constraints
252 if workspace_parameters:
253 req.workspace_parameters = workspace_parameters
256 req.planner_id = planner_id
258 if not keep_upright
is None:
259 current_time = rospy.Time.now()
260 for side_str, vec_E
in keep_upright.iteritems():
261 assert isinstance(vec_E, PyKDL.Vector)
266 q_ku0_name =
'{}KeepUprightJoint0'.format(side_str)
267 q_ku1_name =
'{}KeepUprightJoint1'.format(side_str)
270 for q_idx, joint_name
in enumerate(req.start_state.joint_state.name):
271 if joint_name == q_ku0_name:
272 req.start_state.joint_state.position[q_idx] = q_ku0
273 elif joint_name == q_ku1_name:
274 req.start_state.joint_state.position[q_idx] = q_ku1
276 for goal_constr
in req.goal_constraints:
277 for joint_constr
in goal_constr.joint_constraints:
278 if joint_constr.joint_name == q_ku0_name:
279 joint_constr.position = q_ku0
280 elif joint_constr.joint_name == q_ku1_name:
281 joint_constr.position = q_ku1
284 for q_idx, joint_name
in enumerate(req.start_state.joint_state.name):
285 dbg_str +=
'\'{}\':{},'.format(joint_name,
286 req.start_state.joint_state.position[q_idx])
288 print(
'Planner.plan(): start_q: {}'.format(dbg_str))
289 print(
'Planner.plan(): upright {} vec_E: {}'.format(side_str,
KDL2str(vec_E)))
293 ori_constr = OrientationConstraint()
294 ori_constr.header.frame_id =
'world' 297 ori_constr.link_name =
'{}_keepUprightLink2'.format( side_str )
300 qx, qy, qz, qw = PyKDL.Rotation.RotY(math.radians(-90.0)).GetQuaternion()
301 ori_constr.orientation.x = qx
302 ori_constr.orientation.y = qy
303 ori_constr.orientation.z = qz
304 ori_constr.orientation.w = qw
307 ori_constr.absolute_x_axis_tolerance = math.radians(200.0)
308 ori_constr.absolute_y_axis_tolerance = math.radians(40.0)
309 ori_constr.absolute_z_axis_tolerance = math.radians(40.0)
313 ori_constr.weight = 1.0
315 req.path_constraints.orientation_constraints.append( ori_constr )
317 ori_constr_goal = copy.copy(ori_constr)
318 ori_constr_goal.absolute_x_axis_tolerance = math.radians(200.0)
319 ori_constr_goal.absolute_y_axis_tolerance = math.radians(30.0)
320 ori_constr_goal.absolute_z_axis_tolerance = math.radians(30.0)
323 for goal_constr
in req.goal_constraints:
324 goal_constr.orientation_constraints.append(ori_constr_goal)
326 req.num_planning_attempts = num_planning_attempts
328 req.allowed_planning_time = allowed_planning_time
330 req.max_velocity_scaling_factor = max_velocity_scaling_factor
332 req.max_acceleration_scaling_factor = max_acceleration_scaling_factor
337 request = GetMotionPlanRequest()
338 request.motion_plan_request = req
342 except rospy.service.ServiceException
as e:
343 print "Planner.plan(): could not plan:" 354 len(res.trajectory.joint_trajectory.points) > self.
_max_traj_len:
355 print(
'Planner.plan(): Trajectory is too long: {}'.format(
356 len(res.trajectory.joint_trajectory.points) ))
359 print(
'Found trajectory for joints: {}'.format(res.trajectory.joint_trajectory.joint_names))
360 return res.trajectory.joint_trajectory
364 Updates occupancy map of the planner. 366 @param octomap octomap_msgs.msg.Octomap: Occupancy map. 368 @return Returns True if the octomap was succesfully loaded, False otherwise. 370 req = ApplyPlanningSceneRequest()
381 req.scene.world.octomap.header.frame_id =
"world" 382 req.scene.world.octomap.octomap = octomap
383 req.scene.is_diff =
False 391 Initialization of Python planner interface. 393 @param max_traj_len int: Maximum number of nodes in a planned trajectory. 400 Wait until planner interface is not initialized. 402 @param timeout_s float: Timeout in seconds. 404 @return Returns True if the Python planner interface was succesfully initialized, False otherwise. 407 rospy.wait_for_service(
'/rcprg_planner/plan', timeout=timeout_s)
408 self.
plan_service = rospy.ServiceProxy(
'/rcprg_planner/plan', GetMotionPlan)
413 rospy.wait_for_service(
'/rcprg_planner/processWorld', timeout=timeout_s)
def qMapToConstraints(q_map, tolerance=0.01, group=None)
This function converts dictionary of joint positions to moveit_msgs.Constraints structure.
def waitForInit(self, timeout_s=None)
Wait until planner interface is not initialized.
def processWorld(self, octomap)
Updates occupancy map of the planner.
Class used for obtaining occupancy map (as octomap) from octomap server.
def __init__(self, max_traj_len)
Initialization of Python planner interface.
def getOctomap(self, timeout_s=None)
Get current octomap from octomap server.
def _octomap_callback(self, data)
def plan(self, q_start, goal_constraints, group_name, attached_collision_objects=None, is_diff=False, path_constraints=None, trajectory_constraints=None, workspace_parameters=None, planner_id=None, num_planning_attempts=1, allowed_planning_time=10.0, max_velocity_scaling_factor=1.0, max_acceleration_scaling_factor=1.0, keep_upright=None)
Plan motion in joint space.
Class used as planner interface.
def __init__(self, topic="/octomap_binary")
Initialization, ROS topic subscription.