10 #include <descartes_planner/ladder_graph.h> 16 typedef boost::function<double(const double*, const double*)>
CostFunction;
19 #include <descartes_planner/planning_graph_edge_policy.h> 20 #include <descartes_planner/ladder_graph_dag_search.h> 23 #include <geometry_msgs/Vector3.h> 25 #include <Eigen/Geometry> 35 void convertOrientationVector(
36 const std::vector<geometry_msgs::Vector3>& orients_msg,
37 std::vector<Eigen::Matrix3d>& m_orients)
41 for(
auto v : orients_msg)
44 Eigen::Vector3d eigen_vec;
47 eigen_vec.normalize();
50 Eigen::Vector3d candidate_dir = Eigen::Vector3d::UnitX();
51 if (std::abs(eigen_vec.dot(Eigen::Vector3d::UnitX())) > 0.8)
54 candidate_dir = Eigen::Vector3d::UnitY();
57 Eigen::Vector3d y_vec = eigen_vec.cross(candidate_dir).normalized();
59 Eigen::Vector3d x_vec = y_vec.cross(eigen_vec).normalized();
62 Eigen::Matrix3d m = Eigen::Matrix3d::Identity();
67 m_orients.push_back(m);
76 const choreo_msgs::AssemblySequencePickNPlace& as_pnp,
77 const std::vector<std::vector<planning_scene::PlanningScenePtr>>& planning_scene_subprocess,
78 const double& linear_vel,
const double& linear_disc)
82 assert(linear_disc > 0 && linear_vel > 0);
83 assert(as_pnp.sequenced_elements.size() > 0);
84 assert(as_pnp.sequenced_elements.size() == planning_scene_subprocess.size());
86 std::vector<ConstrainedSegmentPickNPlace> segs(as_pnp.sequenced_elements.size());
88 for(
int i=0;i <as_pnp.sequenced_elements.size(); i++)
90 const auto& se = as_pnp.sequenced_elements[i];
92 assert(se.grasps.size() > 0);
93 segs[i].path_pts.resize(4);
95 segs[i].path_pts[0].resize(2);
96 tf::pointMsgToEigen(se.grasps[0].pick_grasp_approach_pose.position, segs[i].path_pts[0][0]);
99 segs[i].path_pts[1].resize(2);
101 tf::pointMsgToEigen(se.grasps[0].pick_grasp_retreat_pose.position, segs[i].path_pts[1][1]);
103 segs[i].path_pts[2].resize(2);
104 tf::pointMsgToEigen(se.grasps[0].place_grasp_approach_pose.position, segs[i].path_pts[2][0]);
107 segs[i].path_pts[3].resize(2);
109 tf::pointMsgToEigen(se.grasps[0].place_grasp_retreat_pose.position, segs[i].path_pts[3][1]);
112 segs[i].orientations.resize(4);
114 for(
int j=0; j < se.grasps.size(); j++)
116 const auto& g = se.grasps[j];
117 Eigen::Quaterniond
q;
122 segs[i].orientations[0].push_back(q.toRotationMatrix());
125 segs[i].orientations[1].push_back(q.toRotationMatrix());
128 segs[i].orientations[2].push_back(q.toRotationMatrix());
131 segs[i].orientations[3].push_back(q.toRotationMatrix());
135 assert(planning_scene_subprocess[i].
size() == 4);
136 segs[i].planning_scenes = planning_scene_subprocess[i];
138 segs[i].linear_vel = linear_vel;
139 segs[i].linear_disc = linear_disc;
145 std::vector <descartes_planner::ConstrainedSegment>
151 assert(task_sequence.size() > 0);
152 std::vector<ConstrainedSegment> segs(task_sequence.size());
158 auto add_segment = [seg_params]
159 (ConstrainedSegment &seg,
const choreo_msgs::ElementCandidatePoses path_pose)
163 convertOrientationVector(path_pose.feasible_orients, seg.orientations);
169 switch (path_pose.type)
171 case choreo_msgs::ElementCandidatePoses::SUPPORT:
173 seg.process_type = ConstrainedSegment::PROCESS_TYPE::SUPPORT;
176 case choreo_msgs::ElementCandidatePoses::CREATE:
178 seg.process_type = ConstrainedSegment::PROCESS_TYPE::CREATE;
181 case choreo_msgs::ElementCandidatePoses::CONNECT:
183 seg.process_type = ConstrainedSegment::PROCESS_TYPE::CONNECT;
192 for (std::size_t i = 0; i < task_sequence.size(); ++i)
194 add_segment(segs[i], task_sequence[i]);
201 const std::vector<choreo_msgs::ElementCandidatePoses> &task_sequence,
202 const double &linear_vel,
const double &linear_disc,
const double &angular_disc,
const double &retract_dist)
214 const std::vector<double> &start_joint,
double retract_dist,
double TCP_speed,
215 const std::vector <Eigen::Matrix3d> &eef_directions,
216 descartes_core::RobotModelPtr &model,
217 std::vector <std::vector<double>> &retract_jt_traj)
221 ROS_ERROR_STREAM(
"[process planning] recursive retraction sampling fails, retraction dist " 226 const int dof = model->getDOF();
229 Eigen::Affine3d start_pose;
230 if (!model->getFK(start_joint, start_pose))
237 std::vector <Eigen::Affine3d> retract_eef_poses;
238 descartes_planner::LadderGraph graph(model->getDOF());
240 const descartes_core::TimingConstraint timing(retract_dist / TCP_speed);
243 bool first_try =
true;
244 bool exist_pose_not_feasible =
true;
249 retract_eef_poses.clear();
252 Eigen::Matrix3d offset_vec;
256 offset_vec = start_pose.matrix().block<3, 3>(0, 0);
261 offset_vec = eef_directions[sample_id];
264 Eigen::Affine3d retract_pose =
265 start_pose * Eigen::Translation3d(retract_dist * offset_vec.col(2));
267 auto st_pt = start_pose.matrix().col(3).head<3>();
268 auto end_pt = retract_pose.matrix().col(3).head<3>();
269 double ds = (st_pt - end_pt).norm() / 2;
272 graph.resize(path_pts.size());
274 for (
auto &pt : path_pts)
276 Eigen::Affine3d pose = start_pose;
277 pose.matrix().col(3).head<3>() = pt;
279 retract_eef_poses.push_back(pose);
282 exist_pose_not_feasible =
false;
284 for (
int i = 0; i < retract_eef_poses.size(); i++)
286 std::vector <std::vector<double>> retract_jt_vec;
287 retract_jt_vec.clear();
291 retract_jt_vec.push_back(start_joint);
295 if (!model->getAllIK(retract_eef_poses[i], retract_jt_vec))
297 exist_pose_not_feasible =
true;
302 graph.assignRung(i, descartes_core::TrajectoryID::make_nil(), timing, retract_jt_vec);
305 if (!exist_pose_not_feasible)
309 ROS_INFO_STREAM(
"[retraction planning] sampled retraction pose used.");
318 for (std::size_t i = 0; i < graph.size(); i++)
320 if (0 == graph.rungSize(i) || exist_pose_not_feasible)
322 ROS_WARN_STREAM(
"[process planning] retraction sampling fails, recursively decrease retract dist to " 323 << retract_dist * 0.8);
324 return retractPath(start_joint, retract_dist * 0.8, TCP_speed, eef_directions, model, retract_jt_traj);
329 for (std::size_t i = 0; i < graph.size() - 1; ++i)
331 const auto start_idx = i;
332 const auto end_idx = i + 1;
333 const auto &joints1 = graph.getRung(start_idx).data;
334 const auto &joints2 = graph.getRung(end_idx).data;
335 const auto &tm = graph.getRung(end_idx).timing;
337 const auto start_size = joints1.size() / dof;
338 const auto end_size = joints2.size() / dof;
340 descartes_planner::DefaultEdgesWithTime builder(start_size, end_size, dof, tm.upper,
341 model->getJointVelocityLimits());
342 for (
size_t k = 0; k < start_size; k++)
344 const auto start_index = k * dof;
346 for (
size_t j = 0; j < end_size; j++)
348 const auto end_index = j * dof;
350 builder.consider(&joints1[start_index], &joints2[end_index], j);
355 std::vector <descartes_planner::LadderGraph::EdgeList> edges = builder.result();
357 graph.assignEdges(i, std::move(edges));
360 descartes_planner::DAGSearch
search(graph);
361 double cost = search.run();
362 auto path_idxs = search.shortestPath();
364 retract_jt_traj.clear();
365 for (
size_t j = 0; j < path_idxs.size(); ++j)
367 const auto idx = path_idxs[j];
368 const auto *data = graph.vertex(j, idx);
369 retract_jt_traj.push_back(std::vector<double>(data, data + dof));
std::vector< Eigen::Vector3d > discretizePositions(const Eigen::Vector3d &start, const Eigen::Vector3d &stop, const double ds)
boost::function< double(const double *, const double *)> CostFunction
static const double RETRACT_OFFSET_SAMPLE_TIMEOUT
std::size_t size(custom_string const &s)
bool retractPath(const std::vector< double > &start_joint, double retract_dist, double TCP_speed, const std::vector< Eigen::Matrix3d > &eef_directions, descartes_core::RobotModelPtr &model, std::vector< std::vector< double >> &retract_jt_traj)
void vectorMsgToEigen(const geometry_msgs::Vector3 &m, Eigen::Vector3d &e)
void pointMsgToEigen(const geometry_msgs::Point &m, Eigen::Vector3d &e)
static const double MIN_RETRACTION_DIST
#define ROS_WARN_STREAM(args)
static const double JTS_DISC_DELTA
std::vector< descartes_planner::ConstrainedSegment > toDescartesConstrainedPath(const std::vector< choreo_msgs::ElementCandidatePoses > &task_sequence, const double &linear_vel, const double &linear_disc, const double &angular_disc, const double &retract_dist)
int randomSampleInt(int lower, int upper)
#define ROS_INFO_STREAM(args)
void quaternionMsgToEigen(const geometry_msgs::Quaternion &m, Eigen::Quaterniond &e)
#define ROS_ERROR_STREAM(args)
ROSCPP_DECL bool search(const std::string &ns, const std::string &key, std::string &result)