36 from moveit_commander
import (
39 PlanningSceneInterface,
40 MoveItCommanderException,
42 from geometry_msgs.msg
import Pose, PoseStamped
59 Interpreter for simple commands
62 DEFAULT_FILENAME =
"move_group.cfg"
94 return self.
_gdict_gdict.keys()
106 MoveGroupInfoLevel.INFO,
108 +
"\n\nNo groups initialized yet. You must call the 'use' or the 'load' command first.\n",
112 if os.path.isfile(
"cmd/" + cmd):
113 cmd =
"load cmd/" + cmd
115 if cmdlow.startswith(
"use"):
117 return (MoveGroupInfoLevel.INFO,
"\n".join(self.
get_loaded_groupsget_loaded_groups()))
119 clist[0] = clist[0].lower()
121 if clist[0] ==
"use":
122 if clist[1] ==
"previous":
124 if len(clist[1]) == 0:
125 return (MoveGroupInfoLevel.DEBUG,
"OK")
126 if clist[1]
in self.
_gdict_gdict:
129 return (MoveGroupInfoLevel.DEBUG,
"OK")
133 self.
_gdict_gdict[clist[1]] = mg
135 return (MoveGroupInfoLevel.DEBUG,
"OK")
136 except MoveItCommanderException
as e:
138 MoveGroupInfoLevel.FAIL,
139 "Initializing " + clist[1] +
": " + str(e),
143 MoveGroupInfoLevel.FAIL,
144 "Unable to initialize " + clist[1],
146 elif cmdlow.startswith(
"trace"):
147 if cmdlow ==
"trace":
149 MoveGroupInfoLevel.INFO,
150 "trace is on" if self.
_trace_trace
else "trace is off",
152 clist = cmdlow.split()
153 if clist[0] ==
"trace" and clist[1] ==
"on":
155 return (MoveGroupInfoLevel.DEBUG,
"OK")
156 if clist[0] ==
"trace" and clist[1] ==
"off":
158 return (MoveGroupInfoLevel.DEBUG,
"OK")
159 elif cmdlow.startswith(
"load"):
163 return (MoveGroupInfoLevel.WARN,
"Unable to parse load command")
166 if not os.path.isfile(filename):
167 filename =
"cmd/" + filename
171 f = open(filename,
"r")
177 print(
"%s:%d: %s" % (filename, line_num, line_content))
178 comment = line.find(
"#")
180 line = line[0:comment].rstrip()
182 self.
executeexecute(line.rstrip())
184 return (MoveGroupInfoLevel.DEBUG,
"OK")
185 except MoveItCommanderException
as e:
188 MoveGroupInfoLevel.WARN,
189 "Error at %s:%d: %s\n%s"
190 % (filename, line_num, line_content, str(e)),
194 MoveGroupInfoLevel.WARN,
195 "Processing " + filename +
": " + str(e),
200 MoveGroupInfoLevel.WARN,
201 "Error at %s:%d: %s" % (filename, line_num, line_content),
204 return (MoveGroupInfoLevel.WARN,
"Unable to load " + filename)
205 elif cmdlow.startswith(
"save"):
209 return (MoveGroupInfoLevel.WARN,
"Unable to parse save command")
213 f = open(filename,
"w")
214 for gr
in self.
_gdict_gdict.keys():
215 f.write(
"use " + gr +
"\n")
216 known = self.
_gdict_gdict[gr].get_remembered_joint_values()
217 for v
in known.keys():
219 v +
" = [" +
" ".join([str(x)
for x
in known[v]]) +
"]\n"
223 "database " + self.
_db_host_db_host +
" " + str(self.
_db_port_db_port) +
"\n"
225 return (MoveGroupInfoLevel.DEBUG,
"OK")
227 return (MoveGroupInfoLevel.WARN,
"Unable to save " + filename)
232 cmd = cmdorig.lower()
236 return (MoveGroupInfoLevel.DEBUG,
"OK")
239 return (MoveGroupInfoLevel.INFO, g.get_name())
242 return (MoveGroupInfoLevel.INFO, self.
get_helpget_help())
245 known = g.get_remembered_joint_values()
246 return (MoveGroupInfoLevel.INFO,
"[" +
" ".join(known.keys()) +
"]")
249 joints = g.get_joints()
251 MoveGroupInfoLevel.INFO,
253 +
"\n".join([str(i) +
" = " + joints[i]
for i
in range(len(joints))])
265 pose.pose.position.x = 0
266 pose.pose.position.y = 0
268 pose.pose.position.z = -0.0501
269 pose.pose.orientation.x = 0
270 pose.pose.orientation.y = 0
271 pose.pose.orientation.z = 0
272 pose.pose.orientation.w = 1
273 pose.header.stamp = rospy.get_rostime()
274 pose.header.frame_id = self.
_robot_robot.get_root_link()
276 self.
_robot_robot.get_root_link(),
"ground", pose, (3, 3, 0.1)
278 return (MoveGroupInfoLevel.INFO,
"Added ground")
281 if len(g.get_end_effector_link()) > 0:
282 return (MoveGroupInfoLevel.INFO, g.get_end_effector_link())
284 return (MoveGroupInfoLevel.INFO,
"There is no end effector defined")
286 if cmd ==
"database":
288 return (MoveGroupInfoLevel.INFO,
"Not connected to a database")
291 MoveGroupInfoLevel.INFO,
296 return (MoveGroupInfoLevel.INFO, str(self.
_last_plan_last_plan))
298 return (MoveGroupInfoLevel.INFO,
"No previous plan")
300 if cmd ==
"constrain":
301 g.clear_path_constraints()
302 return (MoveGroupInfoLevel.SUCCESS,
"Cleared path constraints")
304 if cmd ==
"tol" or cmd ==
"tolerance":
306 MoveGroupInfoLevel.INFO,
307 "Joint = %0.6g, Position = %0.6g, Orientation = %0.6g"
308 % g.get_goal_tolerance(),
312 return (MoveGroupInfoLevel.INFO, str(g.get_planning_time()))
317 return (MoveGroupInfoLevel.SUCCESS,
"Plan submitted for execution")
320 MoveGroupInfoLevel.WARN,
321 "Failed to submit plan for execution",
324 return (MoveGroupInfoLevel.WARN,
"No motion plan computed")
327 assign_match = re.match(
r"^(\w+)\s*=\s*(\w+)$", cmd)
329 known = g.get_remembered_joint_values()
330 if assign_match.group(2)
in known:
331 g.remember_joint_values(
332 assign_match.group(1), known[assign_match.group(2)]
335 MoveGroupInfoLevel.SUCCESS,
336 assign_match.group(1)
337 +
" is now the same as "
338 + assign_match.group(2),
341 return (MoveGroupInfoLevel.WARN,
"Unknown command: '" + cmd +
"'")
344 set_match = re.match(
r"^(\w+)\s*=\s*\[([\d\.e\-\+\s]+)\]$", cmd)
347 g.remember_joint_values(
348 set_match.group(1), [float(x)
for x
in set_match.group(2).split()]
351 MoveGroupInfoLevel.SUCCESS,
352 "Remembered joint values ["
354 +
"] under the name "
355 + set_match.group(1),
359 MoveGroupInfoLevel.WARN,
360 "Unable to parse joint value [" + set_match.group(2) +
"]",
364 component_match = re.match(
365 r"^(\w+)\s*\[\s*(\d+)\s*\]\s*=\s*([\d\.e\-\+]+)$", cmd
368 known = g.get_remembered_joint_values()
369 if component_match.group(1)
in known:
371 val = known[component_match.group(1)]
372 val[int(component_match.group(2))] = float(component_match.group(3))
373 g.remember_joint_values(component_match.group(1), val)
375 MoveGroupInfoLevel.SUCCESS,
377 + component_match.group(1)
379 + component_match.group(2)
384 MoveGroupInfoLevel.WARN,
385 "Unable to parse index or value in '" + cmd +
"'",
388 return (MoveGroupInfoLevel.WARN,
"Unknown command: '" + cmd +
"'")
390 clist = cmdorig.split()
391 clist[0] = clist[0].lower()
395 known = g.get_remembered_joint_values()
398 MoveGroupInfoLevel.INFO,
399 "[" +
" ".join([str(x)
for x
in known[cmd]]) +
"]",
402 return (MoveGroupInfoLevel.WARN,
"Unknown command: '" + cmd +
"'")
408 if clist[1] ==
"rand" or clist[1] ==
"random":
409 vals = g.get_random_joint_values()
410 g.set_joint_value_target(vals)
413 MoveGroupInfoLevel.SUCCESS,
414 "Moved to random target ["
415 +
" ".join([str(x)
for x
in vals])
420 MoveGroupInfoLevel.FAIL,
421 "Failed while moving to random target ["
422 +
" ".join([str(x)
for x
in vals])
427 g.set_named_target(clist[1])
429 return (MoveGroupInfoLevel.SUCCESS,
"Moved to " + clist[1])
432 MoveGroupInfoLevel.FAIL,
433 "Failed while moving to " + clist[1],
435 except MoveItCommanderException
as e:
437 MoveGroupInfoLevel.WARN,
438 "Going to " + clist[1] +
": " + str(e),
441 return (MoveGroupInfoLevel.WARN, clist[1] +
" is unknown")
442 if clist[0] ==
"plan":
445 if clist[1] ==
"rand" or clist[1] ==
"random":
446 vals = g.get_random_joint_values()
447 g.set_joint_value_target(vals)
451 g.set_named_target(clist[1])
453 except MoveItCommanderException
as e:
455 MoveGroupInfoLevel.WARN,
456 "Planning to " + clist[1] +
": " + str(e),
459 return (MoveGroupInfoLevel.WARN, clist[1] +
" is unknown")
462 len(self.
_last_plan_last_plan.joint_trajectory.points) == 0
463 and len(self.
_last_plan_last_plan.multi_dof_joint_trajectory.points) == 0
468 dest_str =
"[" +
" ".join([str(x)
for x
in vals]) +
"]"
470 return (MoveGroupInfoLevel.SUCCESS,
"Planned to " + dest_str)
473 MoveGroupInfoLevel.FAIL,
474 "Failed while planning to " + dest_str,
476 elif clist[0] ==
"pick":
479 return (MoveGroupInfoLevel.SUCCESS,
"Picked object " + clist[1])
482 MoveGroupInfoLevel.FAIL,
483 "Failed while trying to pick object " + clist[1],
485 elif clist[0] ==
"place":
487 if g.place(clist[1]):
488 return (MoveGroupInfoLevel.SUCCESS,
"Placed object " + clist[1])
491 MoveGroupInfoLevel.FAIL,
492 "Failed while trying to place object " + clist[1],
494 elif clist[0] ==
"planner":
495 g.set_planner_id(clist[1])
496 return (MoveGroupInfoLevel.SUCCESS,
"Planner is now " + clist[1])
497 elif clist[0] ==
"record" or clist[0] ==
"rec":
498 g.remember_joint_values(clist[1])
500 MoveGroupInfoLevel.SUCCESS,
501 "Remembered current joint values under the name " + clist[1],
503 elif clist[0] ==
"rand" or clist[0] ==
"random":
504 g.remember_joint_values(clist[1], g.get_random_joint_values())
506 MoveGroupInfoLevel.SUCCESS,
507 "Remembered random joint values under the name " + clist[1],
509 elif clist[0] ==
"del" or clist[0] ==
"delete":
510 g.forget_joint_values(clist[1])
512 MoveGroupInfoLevel.SUCCESS,
513 "Forgot joint values under the name " + clist[1],
515 elif clist[0] ==
"show":
516 known = g.get_remembered_joint_values()
517 if clist[1]
in known:
519 MoveGroupInfoLevel.INFO,
520 "[" +
" ".join([str(x)
for x
in known[clist[1]]]) +
"]",
524 MoveGroupInfoLevel.WARN,
525 "Joint values for " + clist[1] +
" are not known",
527 elif clist[0] ==
"tol" or clist[0] ==
"tolerance":
529 g.set_goal_tolerance(float(clist[1]))
530 return (MoveGroupInfoLevel.SUCCESS,
"OK")
533 MoveGroupInfoLevel.WARN,
534 "Unable to parse tolerance value '" + clist[1] +
"'",
536 elif clist[0] ==
"time":
538 g.set_planning_time(float(clist[1]))
539 return (MoveGroupInfoLevel.SUCCESS,
"OK")
542 MoveGroupInfoLevel.WARN,
543 "Unable to parse planning duration value '" + clist[1] +
"'",
545 elif clist[0] ==
"constrain":
547 g.set_path_constraints(clist[1])
548 return (MoveGroupInfoLevel.SUCCESS,
"OK")
552 MoveGroupInfoLevel.WARN,
553 "Constraint " + clist[1] +
" is not known.",
556 return (MoveGroupInfoLevel.WARN,
"Not connected to a database.")
557 elif clist[0] ==
"wait":
559 time.sleep(float(clist[1]))
560 return (MoveGroupInfoLevel.SUCCESS, clist[1] +
" seconds passed")
563 MoveGroupInfoLevel.WARN,
564 "Unable to wait '" + clist[1] +
"' seconds",
566 elif clist[0] ==
"database":
568 g.set_constraints_database(clist[1], self.
_db_port_db_port)
571 MoveGroupInfoLevel.SUCCESS,
576 MoveGroupInfoLevel.WARN,
577 "Unable to connect to '"
584 return (MoveGroupInfoLevel.WARN,
"Unknown command: '" + cmd +
"'")
587 if clist[0] ==
"go" and clist[1]
in self.
GO_DIRSGO_DIRS:
590 offset = float(clist[2])
591 (axis, factor) = self.
GO_DIRSGO_DIRS[clist[1]]
592 return self.
command_go_offsetcommand_go_offset(g, offset, factor, axis, clist[1])
593 except MoveItCommanderException
as e:
595 MoveGroupInfoLevel.WARN,
596 "Going " + clist[1] +
": " + str(e),
600 MoveGroupInfoLevel.WARN,
601 "Unable to parse distance '" + clist[2] +
"'",
603 elif clist[0] ==
"allow" and (clist[1] ==
"look" or clist[1] ==
"looking"):
606 or clist[2] ==
"true"
608 or clist[2] ==
"True"
610 g.allow_looking(
True)
612 g.allow_looking(
False)
613 return (MoveGroupInfoLevel.DEBUG,
"OK")
614 elif clist[0] ==
"allow" and (
615 clist[1] ==
"replan" or clist[1] ==
"replanning"
619 or clist[2] ==
"true"
621 or clist[2] ==
"True"
623 g.allow_replanning(
True)
625 g.allow_replanning(
False)
626 return (MoveGroupInfoLevel.DEBUG,
"OK")
627 elif clist[0] ==
"database":
629 g.set_constraints_database(clist[1], int(clist[2]))
631 self.
_db_port_db_port = int(clist[2])
633 MoveGroupInfoLevel.SUCCESS,
639 MoveGroupInfoLevel.WARN,
640 "Unable to connect to '" + clist[1] +
":" + clist[2] +
"'",
643 if clist[0] ==
"rotate":
645 g.set_rpy_target([float(x)
for x
in clist[1:]])
647 return (MoveGroupInfoLevel.SUCCESS,
"Rotation complete")
650 MoveGroupInfoLevel.FAIL,
651 "Failed while rotating to " +
" ".join(clist[1:]),
653 except MoveItCommanderException
as e:
654 return (MoveGroupInfoLevel.WARN, str(e))
657 MoveGroupInfoLevel.WARN,
658 "Unable to parse X-Y-Z rotation values '"
659 +
" ".join(clist[1:])
667 if clist[7] ==
"approx" or clist[7] ==
"approximate":
671 p.position.x = float(clist[1])
672 p.position.y = float(clist[2])
673 p.position.z = float(clist[3])
674 q = tf.transformations.quaternion_from_euler(
675 float(clist[4]), float(clist[5]), float(clist[6])
677 p.orientation.x = q[0]
678 p.orientation.y = q[1]
679 p.orientation.z = q[2]
680 p.orientation.w = q[3]
682 g.set_joint_value_target(p,
True)
687 MoveGroupInfoLevel.SUCCESS,
688 "Moved to pose target\n%s\n" % (str(p)),
692 MoveGroupInfoLevel.FAIL,
693 "Failed while moving to pose \n%s\n" % (str(p)),
695 except MoveItCommanderException
as e:
697 MoveGroupInfoLevel.WARN,
698 "Going to pose target: %s" % (str(e)),
702 MoveGroupInfoLevel.WARN,
703 "Unable to parse pose '" +
" ".join(clist[1:]) +
"'",
706 return (MoveGroupInfoLevel.WARN,
"Unknown command: '" + cmd +
"'")
709 known = g.get_remembered_joint_values()
711 for k
in known.keys():
712 res.append(k +
" = [" +
" ".join([str(x)
for x
in known[k]]) +
"]")
713 return (MoveGroupInfoLevel.INFO,
"\n".join(res))
718 +
", ".join([str(x)
for x
in g.get_current_joint_values()])
721 if len(g.get_end_effector_link()) > 0:
725 + g.get_end_effector_link()
727 + str(g.get_current_pose())
733 + g.get_end_effector_link()
735 + str(g.get_current_rpy())
737 return (MoveGroupInfoLevel.INFO, res)
740 if g.has_end_effector_link():
742 g.shift_pose_target(dimension_index, factor * offset)
745 MoveGroupInfoLevel.SUCCESS,
746 "Moved " + direction_name +
" by " + str(offset) +
" m",
750 MoveGroupInfoLevel.FAIL,
751 "Failed while moving " + direction_name,
753 except MoveItCommanderException
as e:
754 return (MoveGroupInfoLevel.WARN, str(e))
756 return (MoveGroupInfoLevel.WARN,
"Unable to process pose update")
759 MoveGroupInfoLevel.WARN,
760 "No known end effector. Cannot move " + direction_name,
764 cmd = cmdorig.lower()
773 res.append(
"Known commands:")
774 res.append(
" help show this screen")
775 res.append(
" allow looking <true|false> enable/disable looking around")
776 res.append(
" allow replanning <true|false> enable/disable replanning")
777 res.append(
" constrain clear path constraints")
779 " constrain <name> use the constraint <name> as a path constraint"
781 res.append(
" current show the current state of the active group")
783 " database display the current database connection (if any)"
786 " delete <name> forget the joint values under the name <name>"
789 " eef print the name of the end effector attached to the current group"
791 res.append(
" execute execute a previously computed motion plan")
793 " go <name> plan and execute a motion to the state <name>"
795 res.append(
" go rand plan and execute a motion to a random state")
797 " go <dir> <dx>| plan and execute a motion in direction up|down|left|right|forward|backward for distance <dx>"
799 res.append(
" ground add a ground plane to the planning scene")
801 " id|which display the name of the group that is operated on"
804 " joints display names of the joints in the active group"
807 " load [<file>] load a set of interpreted commands from a file"
809 res.append(
" pick <name> pick up object <name>")
810 res.append(
" place <name> place object <name>")
811 res.append(
" plan <name> plan a motion to the state <name>")
812 res.append(
" plan rand plan a motion to a random state")
813 res.append(
" planner <name> use planner <name> to plan next motion")
815 " record <name> record the current joint values under the name <name>"
818 " rotate <x> <y> <z> plan and execute a motion to a specified orientation (about the X,Y,Z axes)"
821 " save [<file>] save the currently known variables as a set of commands"
824 " show display the names and values of the known states"
826 res.append(
" show <name> display the value of a state")
827 res.append(
" stop stop the active group")
828 res.append(
" time show the configured allowed planning time")
829 res.append(
" time <val> set the allowed planning time")
831 " tolerance show the tolerance for reaching the goal region"
834 " tolerance <val> set the tolerance for reaching the goal region"
836 res.append(
" trace <on|off> enable/disable replanning or looking around")
838 " use <name> switch to using the group named <name> (and load it if necessary)"
840 res.append(
" use|groups show the group names that are already loaded")
841 res.append(
" vars display the names of the known states")
842 res.append(
" wait <dt> sleep for <dt> seconds")
843 res.append(
" x = y assign the value of y to x")
844 res.append(
" x = [v1 v2...] assign a vector of values to x")
845 res.append(
" x[idx] = val assign a value to dimension idx of x")
846 return "\n".join(res)
852 known_vars = self.
get_active_groupget_active_group().get_remembered_joint_values().keys()
853 known_constr = self.
get_active_groupget_active_group().get_known_constraints()
854 groups = self.
_robot_robot.get_group_names()
856 "go": [
"up",
"down",
"left",
"right",
"backward",
"forward",
"random"]
859 "record": known_vars,
862 "delete": known_vars,
871 "allow": [
"replanning",
"looking"],
872 "constrain": known_constr,
def resolve_command_alias(self, cmdorig)
def execute_generic_command(self, cmd)
def execute_group_command(self, g, cmdorig)
def command_show(self, g)
def get_active_group(self)
def command_go_offset(self, g, offset, factor, dimension_index, direction_name)
def command_current(self, g)
def get_loaded_groups(self)
_planning_scene_interface
void print(PropagationDistanceField &pdf, int numX, int numY, int numZ)