00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <moveit/move_group_interface/move_group.h>
00038 #include <moveit/py_bindings_tools/roscpp_initializer.h>
00039 #include <moveit/py_bindings_tools/py_conversions.h>
00040 #include <eigen_conversions/eigen_msg.h>
00041
00042 #include <boost/python.hpp>
00043 #include <boost/shared_ptr.hpp>
00044 #include <Python.h>
00045
00048 namespace bp = boost::python;
00049
00050 namespace moveit
00051 {
00052 namespace planning_interface
00053 {
00054
00055 class MoveGroupWrapper : protected py_bindings_tools::ROScppInitializer,
00056 public MoveGroup
00057 {
00058 public:
00059
00060
00061 MoveGroupWrapper(const std::string &group_name, const std::string &robot_description) :
00062 py_bindings_tools::ROScppInitializer(),
00063 MoveGroup(Options(group_name, robot_description), boost::shared_ptr<tf::Transformer>(), ros::Duration(5, 0))
00064 {
00065 }
00066
00067 bool setJointValueTargetPerJointPythonList(const std::string &joint, bp::list &values)
00068 {
00069 return setJointValueTarget(joint, py_bindings_tools::doubleFromList(values));
00070 }
00071
00072 bool setJointValueTargetPythonList(bp::list &values)
00073 {
00074 return setJointValueTarget(py_bindings_tools::doubleFromList(values));
00075 }
00076
00077 bool setJointValueTargetPythonDict(bp::dict &values)
00078 {
00079 bp::list k = values.keys();
00080 int l = bp::len(k);
00081 std::map<std::string, double> v;
00082 for (int i = 0; i < l ; ++i)
00083 v[bp::extract<std::string>(k[i])] = bp::extract<double>(values[k[i]]);
00084 return setJointValueTarget(v);
00085 }
00086
00087 void rememberJointValuesFromPythonList(const std::string &string, bp::list &values)
00088 {
00089 rememberJointValues(string, py_bindings_tools::doubleFromList(values));
00090 }
00091
00092 const char* getPlanningFrameCStr() const
00093 {
00094 return getPlanningFrame().c_str();
00095 }
00096
00097 bp::list getJointsList() const
00098 {
00099 return py_bindings_tools::listFromString(getJoints());
00100 }
00101
00102 bp::list getCurrentJointValuesList()
00103 {
00104 return py_bindings_tools::listFromDouble(getCurrentJointValues());
00105 }
00106
00107 bp::list getRandomJointValuesList()
00108 {
00109 return py_bindings_tools::listFromDouble(getRandomJointValues());
00110 }
00111
00112 bp::dict getRememberedJointValuesPython() const
00113 {
00114 const std::map<std::string, std::vector<double> > &rv = getRememberedJointValues();
00115 bp::dict d;
00116 for (std::map<std::string, std::vector<double> >::const_iterator it = rv.begin() ; it != rv.end() ; ++it)
00117 d[it->first] = py_bindings_tools::listFromDouble(it->second);
00118 return d;
00119 }
00120
00121 bp::list convertPoseToList(const geometry_msgs::Pose &pose) const
00122 {
00123 std::vector<double> v(7);
00124 v[0] = pose.position.x;
00125 v[1] = pose.position.y;
00126 v[2] = pose.position.z;
00127 v[3] = pose.orientation.x;
00128 v[4] = pose.orientation.y;
00129 v[5] = pose.orientation.z;
00130 v[6] = pose.orientation.w;
00131 return moveit::py_bindings_tools::listFromDouble(v);
00132 }
00133
00134 bp::list convertTransformToList(const geometry_msgs::Transform &tr) const
00135 {
00136 std::vector<double> v(7);
00137 v[0] = tr.translation.x;
00138 v[1] = tr.translation.y;
00139 v[2] = tr.translation.z;
00140 v[3] = tr.rotation.x;
00141 v[4] = tr.rotation.y;
00142 v[5] = tr.rotation.z;
00143 v[6] = tr.rotation.w;
00144 return py_bindings_tools::listFromDouble(v);
00145 }
00146
00147 void convertListToTransform(const bp::list &l, geometry_msgs::Transform &tr) const
00148 {
00149 std::vector<double> v = py_bindings_tools::doubleFromList(l);
00150 tr.translation.x = v[0];
00151 tr.translation.y = v[1];
00152 tr.translation.z = v[2];
00153 tr.rotation.x = v[3];
00154 tr.rotation.y = v[4];
00155 tr.rotation.z = v[5];
00156 tr.rotation.w = v[6];
00157 }
00158
00159 void convertListToPose(const bp::list &l, geometry_msgs::Pose &p) const
00160 {
00161 std::vector<double> v = py_bindings_tools::doubleFromList(l);
00162 p.position.x = v[0];
00163 p.position.y = v[1];
00164 p.position.z = v[2];
00165 p.orientation.x = v[3];
00166 p.orientation.y = v[4];
00167 p.orientation.z = v[5];
00168 p.orientation.w = v[6];
00169 }
00170
00171 bp::list getCurrentRPYPython(const std::string &end_effector_link = "")
00172 {
00173 return py_bindings_tools::listFromDouble(getCurrentRPY(end_effector_link));
00174 }
00175
00176 bp::list getCurrentPosePython(const std::string &end_effector_link = "")
00177 {
00178 geometry_msgs::PoseStamped pose = getCurrentPose(end_effector_link);
00179 return convertPoseToList(pose.pose);
00180 }
00181
00182 bp::list getRandomPosePython(const std::string &end_effector_link = "")
00183 {
00184 geometry_msgs::PoseStamped pose = getRandomPose(end_effector_link);
00185 return convertPoseToList(pose.pose);
00186 }
00187
00188 bp::list getKnownConstraintsList() const
00189 {
00190 return py_bindings_tools::listFromString(getKnownConstraints());
00191 }
00192
00193 bool placePython(const std::string &object_name, const bp::list &pose)
00194 {
00195 geometry_msgs::PoseStamped msg;
00196 convertListToPose(pose, msg.pose);
00197 msg.header.frame_id = getPoseReferenceFrame();
00198 msg.header.stamp = ros::Time::now();
00199 return place(object_name, msg);
00200 }
00201
00202 void convertListToArrayOfPoses(const bp::list &poses, std::vector<geometry_msgs::Pose> &msg)
00203 {
00204 int l = bp::len(poses);
00205 for (int i = 0; i < l ; ++i)
00206 {
00207 const bp::list &pose = bp::extract<bp::list>(poses[i]);
00208 std::vector<double> v = py_bindings_tools::doubleFromList(pose);
00209 if (v.size() == 6 || v.size() == 7)
00210 {
00211 Eigen::Affine3d p = v.size() == 6 ?
00212 Eigen::Affine3d(Eigen::AngleAxisd(v[3], Eigen::Vector3d::UnitX())
00213 * Eigen::AngleAxisd(v[4], Eigen::Vector3d::UnitY())
00214 * Eigen::AngleAxisd(v[5], Eigen::Vector3d::UnitZ())) :
00215 Eigen::Affine3d(Eigen::Quaterniond(v[6], v[3], v[4], v[5]));
00216 p.translation() = Eigen::Vector3d(v[0], v[1], v[2]);
00217 geometry_msgs::Pose pm;
00218 tf::poseEigenToMsg(p, pm);
00219 msg.push_back(pm);
00220 }
00221 else
00222 ROS_WARN("Incorrect number of values for a pose: %u", (unsigned int)v.size());
00223 }
00224 }
00225
00226 bool setPoseTargetsPython(bp::list &poses, const std::string &end_effector_link = "")
00227 {
00228 std::vector<geometry_msgs::Pose> msg;
00229 convertListToArrayOfPoses(poses, msg);
00230 return setPoseTargets(msg, end_effector_link);
00231 }
00232
00233 bool setPoseTargetPython(bp::list &pose, const std::string &end_effector_link = "")
00234 {
00235 std::vector<double> v = py_bindings_tools::doubleFromList(pose);
00236 geometry_msgs::Pose msg;
00237 if (v.size() == 6)
00238 tf::quaternionTFToMsg(tf::createQuaternionFromRPY(v[3], v[4], v[5]), msg.orientation);
00239 else
00240 if (v.size() == 7)
00241 {
00242 msg.orientation.x = v[3];
00243 msg.orientation.y = v[4];
00244 msg.orientation.z = v[5];
00245 msg.orientation.w = v[6];
00246 }
00247 else
00248 {
00249 ROS_ERROR("Pose description expected to consist of either 6 or 7 values");
00250 return false;
00251 }
00252 msg.position.x = v[0];
00253 msg.position.y = v[1];
00254 msg.position.z = v[2];
00255 return setPoseTarget(msg, end_effector_link);
00256 }
00257
00258 const char* getEndEffectorLinkCStr() const
00259 {
00260 return getEndEffectorLink().c_str();
00261 }
00262
00263 const char* getPoseReferenceFrameCStr() const
00264 {
00265 return getPoseReferenceFrame().c_str();
00266 }
00267
00268 const char* getNameCStr() const
00269 {
00270 return getName().c_str();
00271 }
00272
00273 bool executePython(bp::dict &plan_dict)
00274 {
00275 MoveGroup::Plan plan;
00276 convertDictToTrajectory(plan_dict, plan.trajectory_);
00277 return execute(plan);
00278 }
00279
00280 void convertDictToTrajectory(const bp::dict &plan, moveit_msgs::RobotTrajectory &traj) const
00281 {
00282 traj.joint_trajectory.joint_names = py_bindings_tools::stringFromList(bp::extract<bp::list>(plan["joint_trajectory"]["joint_names"]));
00283 traj.multi_dof_joint_trajectory.joint_names = py_bindings_tools::stringFromList(bp::extract<bp::list>(plan["multi_dof_joint_trajectory"]["joint_names"]));
00284 traj.joint_trajectory.header.frame_id = bp::extract<std::string>(plan["joint_trajectory"]["frame_id"]);
00285 traj.multi_dof_joint_trajectory.header.frame_id = bp::extract<std::string>(plan["multi_dof_joint_trajectory"]["frame_id"]);
00286
00287 const bp::list &joint_trajectory_points = bp::extract<bp::list>(plan["joint_trajectory"]["points"]);
00288 int l = boost::python::len(joint_trajectory_points);
00289 for (int i = 0 ; i < l ; ++i)
00290 {
00291 trajectory_msgs::JointTrajectoryPoint pt;
00292 pt.positions = py_bindings_tools::doubleFromList(bp::extract<bp::list>(joint_trajectory_points[i]["positions"]));
00293 pt.velocities = py_bindings_tools::doubleFromList(bp::extract<bp::list>(joint_trajectory_points[i]["velocities"]));
00294 pt.accelerations = py_bindings_tools::doubleFromList(bp::extract<bp::list>(joint_trajectory_points[i]["accelerations"]));
00295 pt.time_from_start = ros::Duration(bp::extract<double>(joint_trajectory_points[i]["time_from_start"]));
00296 traj.joint_trajectory.points.push_back(pt);
00297 }
00298 const bp::list &multi_dof_joint_trajectory_points = bp::extract<bp::list>(plan["multi_dof_joint_trajectory"]["points"]);
00299 l = boost::python::len(multi_dof_joint_trajectory_points);
00300 for (int i = 0 ; i < l ; ++i)
00301 {
00302 moveit_msgs::MultiDOFJointTrajectoryPoint pt;
00303 const bp::list &tf = bp::extract<bp::list>(multi_dof_joint_trajectory_points[i]["transforms"]);
00304 int lk = boost::python::len(tf);
00305 for (int k = 0 ; k < lk ; ++k)
00306 {
00307 geometry_msgs::Transform tf_msg;
00308 convertListToTransform(bp::extract<bp::list>(tf[k]), tf_msg);
00309 pt.transforms.push_back(tf_msg);
00310 }
00311 pt.time_from_start = ros::Duration(bp::extract<double>(multi_dof_joint_trajectory_points[i]["time_from_start"]));
00312 traj.multi_dof_joint_trajectory.points.push_back(pt);
00313 }
00314
00315 }
00316
00317 bp::dict convertTrajectoryToDict(moveit_msgs::RobotTrajectory &traj) const
00318 {
00319 bp::list joint_names = py_bindings_tools::listFromString(traj.joint_trajectory.joint_names);
00320 bp::dict joint_trajectory, multi_dof_joint_trajectory;
00321 joint_trajectory["joint_names"] = joint_names;
00322 multi_dof_joint_trajectory["joint_names"] = joint_names;
00323 joint_trajectory["frame_id"] = traj.joint_trajectory.header.frame_id;
00324 multi_dof_joint_trajectory["frame_id"] = traj.multi_dof_joint_trajectory.header.frame_id;
00325
00326 bp::list joint_traj_points;
00327 for (std::vector<trajectory_msgs::JointTrajectoryPoint>::const_iterator it = traj.joint_trajectory.points.begin() ;
00328 it != traj.joint_trajectory.points.end() ; ++it)
00329 {
00330 bp::dict joint_traj_point;
00331 joint_traj_point["positions"] = py_bindings_tools::listFromDouble(it->positions);
00332 joint_traj_point["velocities"] = py_bindings_tools::listFromDouble(it->velocities);
00333 joint_traj_point["accelerations"] = py_bindings_tools::listFromDouble(it->accelerations);
00334 joint_traj_point["time_from_start"] = it->time_from_start.toSec();
00335 joint_traj_points.append(joint_traj_point);
00336 }
00337
00338 joint_trajectory["points"] = joint_traj_points;
00339
00340 bp::list multi_dof_traj_points;
00341 for (std::vector<moveit_msgs::MultiDOFJointTrajectoryPoint>::const_iterator it = traj.multi_dof_joint_trajectory.points.begin() ;
00342 it != traj.multi_dof_joint_trajectory.points.end() ; ++it)
00343 {
00344 bp::dict multi_dof_traj_point;
00345 bp::list transforms;
00346 for (std::vector<geometry_msgs::Transform>::const_iterator itr = it->transforms.begin() ; itr != it->transforms.end() ; ++itr)
00347 transforms.append(convertTransformToList(*itr));
00348 multi_dof_traj_point["transforms"] = transforms;
00349 multi_dof_traj_point["time_from_start"] = it->time_from_start.toSec();
00350 multi_dof_traj_points.append(multi_dof_traj_point);
00351 }
00352 multi_dof_joint_trajectory["points"] = multi_dof_traj_points;
00353
00354 bp::dict plan_dict;
00355 plan_dict["joint_trajectory"] = joint_trajectory;
00356 plan_dict["multi_dof_joint_trajectory"] = multi_dof_joint_trajectory;
00357 return plan_dict;
00358 }
00359
00360 bp::dict getPlanPythonDict()
00361 {
00362 MoveGroup::Plan plan;
00363 MoveGroup::plan(plan);
00364 return convertTrajectoryToDict(plan.trajectory_);
00365 }
00366
00367 bp::tuple computeCartesianPathPython(const bp::list &waypoints, double eef_step, double jump_threshold, bool avoid_collisions)
00368 {
00369 std::vector<geometry_msgs::Pose> poses;
00370 convertListToArrayOfPoses(waypoints, poses);
00371 moveit_msgs::RobotTrajectory trajectory;
00372 double fraction = computeCartesianPath(poses, eef_step, jump_threshold, trajectory, avoid_collisions);
00373 return bp::make_tuple(convertTrajectoryToDict(trajectory), fraction);
00374 }
00375
00376 };
00377
00378 static void wrap_move_group_interface()
00379 {
00380 bp::class_<MoveGroupWrapper> MoveGroupClass("MoveGroup", bp::init<std::string, std::string>());
00381
00382 MoveGroupClass.def("async_move", &MoveGroupWrapper::asyncMove);
00383 MoveGroupClass.def("move", &MoveGroupWrapper::move);
00384 MoveGroupClass.def("execute", &MoveGroupWrapper::executePython);
00385 bool (MoveGroupWrapper::*pick_1)(const std::string&) = &MoveGroupWrapper::pick;
00386 MoveGroupClass.def("pick", pick_1);
00387 MoveGroupClass.def("place", &MoveGroupWrapper::placePython);
00388 MoveGroupClass.def("stop", &MoveGroupWrapper::stop);
00389
00390 MoveGroupClass.def("get_name", &MoveGroupWrapper::getNameCStr);
00391 MoveGroupClass.def("get_planning_frame", &MoveGroupWrapper::getPlanningFrameCStr);
00392
00393 MoveGroupClass.def("get_joints", &MoveGroupWrapper::getJointsList);
00394 MoveGroupClass.def("get_variable_count", &MoveGroupWrapper::getVariableCount);
00395 MoveGroupClass.def("allow_looking", &MoveGroupWrapper::allowLooking);
00396 MoveGroupClass.def("allow_replanning", &MoveGroupWrapper::allowReplanning);
00397
00398 MoveGroupClass.def("set_pose_reference_frame", &MoveGroupWrapper::setPoseReferenceFrame);
00399
00400 MoveGroupClass.def("set_pose_reference_frame", &MoveGroupWrapper::setPoseReferenceFrame);
00401 MoveGroupClass.def("set_end_effector_link", &MoveGroupWrapper::setEndEffectorLink);
00402 MoveGroupClass.def("get_end_effector_link", &MoveGroupWrapper::getEndEffectorLinkCStr);
00403 MoveGroupClass.def("get_pose_reference_frame", &MoveGroupWrapper::getPoseReferenceFrameCStr);
00404
00405 MoveGroupClass.def("set_pose_target", &MoveGroupWrapper::setPoseTargetPython);
00406
00407 MoveGroupClass.def("set_pose_targets", &MoveGroupWrapper::setPoseTargetsPython);
00408
00409 MoveGroupClass.def("set_position_target", &MoveGroupWrapper::setPositionTarget);
00410 MoveGroupClass.def("set_rpy_target", &MoveGroupWrapper::setRPYTarget);
00411 MoveGroupClass.def("set_orientation_target", &MoveGroupWrapper::setOrientationTarget);
00412
00413 MoveGroupClass.def("get_current_pose", &MoveGroupWrapper::getCurrentPosePython);
00414 MoveGroupClass.def("get_current_rpy", &MoveGroupWrapper::getCurrentRPYPython);
00415
00416 MoveGroupClass.def("get_random_pose", &MoveGroupWrapper::getRandomPosePython);
00417
00418 MoveGroupClass.def("clear_pose_target", &MoveGroupWrapper::clearPoseTarget);
00419 MoveGroupClass.def("clear_pose_targets", &MoveGroupWrapper::clearPoseTargets);
00420
00421 MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPythonList);
00422 MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPythonDict);
00423 MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPerJointPythonList);
00424 bool (MoveGroupWrapper::*setJointValueTarget_4)(const std::string&, double) = &MoveGroupWrapper::setJointValueTarget;
00425 MoveGroupClass.def("set_joint_value_target", setJointValueTarget_4);
00426
00427 bool (MoveGroupWrapper::*setJointValueTarget_5)(const sensor_msgs::JointState &) = &MoveGroupWrapper::setJointValueTarget;
00428 MoveGroupClass.def("set_joint_value_target", setJointValueTarget_5);
00429
00430 MoveGroupClass.def("set_named_target", &MoveGroupWrapper::setNamedTarget);
00431 MoveGroupClass.def("set_random_target", &MoveGroupWrapper::setRandomTarget);
00432
00433 void (MoveGroupWrapper::*rememberJointValues_2)(const std::string&) = &MoveGroupWrapper::rememberJointValues;
00434 MoveGroupClass.def("remember_joint_values", rememberJointValues_2);
00435
00436 MoveGroupClass.def("remember_joint_values", &MoveGroupWrapper::rememberJointValuesFromPythonList);
00437
00438 MoveGroupClass.def("get_current_joint_values", &MoveGroupWrapper::getCurrentJointValuesList);
00439 MoveGroupClass.def("get_random_joint_values", &MoveGroupWrapper::getRandomJointValuesList);
00440 MoveGroupClass.def("get_remembered_joint_values", &MoveGroupWrapper::getRememberedJointValuesPython);
00441
00442 MoveGroupClass.def("forget_joint_values", &MoveGroupWrapper::forgetJointValues);
00443
00444 MoveGroupClass.def("get_goal_joint_tolerance", &MoveGroupWrapper::getGoalJointTolerance);
00445 MoveGroupClass.def("get_goal_position_tolerance", &MoveGroupWrapper::getGoalPositionTolerance);
00446 MoveGroupClass.def("get_goal_orientation_tolerance", &MoveGroupWrapper::getGoalOrientationTolerance);
00447
00448 MoveGroupClass.def("set_goal_joint_tolerance", &MoveGroupWrapper::setGoalJointTolerance);
00449 MoveGroupClass.def("set_goal_position_tolerance", &MoveGroupWrapper::setGoalPositionTolerance);
00450 MoveGroupClass.def("set_goal_orientation_tolerance", &MoveGroupWrapper::setGoalOrientationTolerance);
00451 MoveGroupClass.def("set_goal_tolerance", &MoveGroupWrapper::setGoalTolerance);
00452
00453 bool (MoveGroupWrapper::*setPathConstraints_1)(const std::string&) = &MoveGroupWrapper::setPathConstraints;
00454 MoveGroupClass.def("set_path_constraints", setPathConstraints_1);
00455
00456 MoveGroupClass.def("clear_path_constraints", &MoveGroupWrapper::clearPathConstraints);
00457 MoveGroupClass.def("get_known_constraints", &MoveGroupWrapper::getKnownConstraintsList);
00458 MoveGroupClass.def("set_constraints_database", &MoveGroupWrapper::setConstraintsDatabase);
00459 MoveGroupClass.def("set_workspace", &MoveGroupWrapper::setWorkspace);
00460 MoveGroupClass.def("set_planning_time", &MoveGroupWrapper::setPlanningTime);
00461 MoveGroupClass.def("get_planning_time", &MoveGroupWrapper::getPlanningTime);
00462 MoveGroupClass.def("set_planner_id", &MoveGroupWrapper::setPlannerId);
00463 MoveGroupClass.def("compute_plan", &MoveGroupWrapper::getPlanPythonDict);
00464 MoveGroupClass.def("compute_cartesian_path", &MoveGroupWrapper::computeCartesianPathPython);
00465 MoveGroupClass.def("set_support_surface_name", &MoveGroupWrapper::setSupportSurfaceName);
00466 }
00467
00468 }
00469 }
00470
00471 BOOST_PYTHON_MODULE(_moveit_move_group_interface)
00472 {
00473 using namespace moveit::planning_interface;
00474 wrap_move_group_interface();
00475 }
00476