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 #include "jsk_footstep_planner/footstep_graph.h"
00037 #include <sstream>
00038
00039 namespace jsk_footstep_planner
00040 {
00041 void FootstepGraph::setBasicSuccessors(
00042 std::vector<Eigen::Affine3f> left_to_right_successors)
00043 {
00044 successors_from_left_to_right_ = left_to_right_successors;
00045 for (size_t i = 0; i < successors_from_left_to_right_.size(); i++) {
00046 Eigen::Affine3f transform = successors_from_left_to_right_[i];
00047 float roll, pitch, yaw;
00048 pcl::getEulerAngles(transform, roll, pitch, yaw);
00049 Eigen::Vector3f translation = transform.translation();
00050 Eigen::Affine3f flipped_transform
00051 = Eigen::Translation3f(translation[0], -translation[1], translation[2])
00052 * Eigen::Quaternionf(Eigen::AngleAxisf(-yaw, Eigen::Vector3f::UnitZ()));
00053 successors_from_right_to_left_.push_back(flipped_transform);
00054 }
00055
00056
00057 for (size_t i = 0; i < successors_from_left_to_right_.size(); i++) {
00058 Eigen::Affine3f transform = successors_from_left_to_right_[i];
00059 double dist = transform.translation().norm();
00060 if (dist > max_successor_distance_) {
00061 max_successor_distance_ = dist;
00062 }
00063 double rot = Eigen::AngleAxisf(transform.rotation()).angle();
00064 if (rot > max_successor_rotation_) {
00065 max_successor_rotation_ = rot;
00066 }
00067 }
00068 }
00069
00070 bool FootstepGraph::isGoal(StatePtr state)
00071 {
00072 FootstepState::Ptr goal = getGoal(state->getLeg());
00073 if (publish_progress_) {
00074 jsk_footstep_msgs::FootstepArray msg;
00075 msg.header.frame_id = "odom";
00076 msg.header.stamp = ros::Time::now();
00077 msg.footsteps.push_back(*state->toROSMsg());
00078 pub_progress_.publish(msg);
00079 }
00080 Eigen::Affine3f pose = state->getPose();
00081 Eigen::Affine3f goal_pose = goal->getPose();
00082 Eigen::Affine3f transformation = pose.inverse() * goal_pose;
00083 return (pos_goal_thr_ > transformation.translation().norm()) &&
00084 (rot_goal_thr_ > std::abs(Eigen::AngleAxisf(transformation.rotation()).angle()));
00085 }
00086
00087 std::string FootstepGraph::infoString() const
00088 {
00089 std::stringstream ss;
00090 ss << "footstep_graph" << std::endl;
00091 ss << " pos_goal_thr: " << pos_goal_thr_ << std::endl;
00092 ss << " rot_goal_thr: " << rot_goal_thr_ << std::endl;
00093 ss << " use_pointcloud_model: " << use_pointcloud_model_ << std::endl;
00094 ss << " lazy_projection: " << lazy_projection_ << std::endl;
00095 ss << " local_movement: " << local_movement_ << std::endl;
00096 ss << " transition_limit: " << transition_limit_ << std::endl;
00097 ss << " local_move_x: " << local_move_x_ << std::endl;
00098 ss << " local_move_y: " << local_move_y_ << std::endl;
00099 ss << " local_move_theta: " << local_move_theta_ << std::endl;
00100 ss << " local_move_x_num: " << local_move_x_num_ << std::endl;
00101 ss << " local_move_y_num: " << local_move_y_num_ << std::endl;
00102 ss << " local_move_theta_num: " << local_move_theta_num_ << std::endl;
00103 ss << " resolution: ["
00104 << resolution_[0] << ", "
00105 << resolution_[1] << ", "
00106 << resolution_[2] << "]"
00107 << std::endl;
00108 ss << " plane_estimation_max_iterations: " << plane_estimation_max_iterations_ << std::endl;
00109 ss << " plane_estimation_min_inliers: " << plane_estimation_min_inliers_ << std::endl;
00110 ss << " plane_estimation_outlier_threshold: " << plane_estimation_outlier_threshold_ << std::endl;
00111 ss << " support_check_x_sampling: " << support_check_x_sampling_ << std::endl;
00112 ss << " support_check_y_sampling: " << support_check_y_sampling_ << std::endl;
00113 ss << " support_check_vertex_neighbor_threshold: " << support_check_vertex_neighbor_threshold_ << std::endl;
00114
00115 return ss.str();
00116 }
00117
00118 std::vector<FootstepState::Ptr>
00119 FootstepGraph::localMoveFootstepState(FootstepState::Ptr in)
00120 {
00121 std::vector<FootstepState::Ptr> moved_states;
00122 moved_states.reserve(local_move_x_num_ * local_move_y_num_ * local_move_theta_num_ * 8);
00123 for (size_t xi = - local_move_x_num_; xi <= local_move_x_num_; xi++) {
00124 for (size_t yi = - local_move_y_num_; yi <= local_move_y_num_; yi++) {
00125 for (size_t thetai = - local_move_theta_num_; thetai <= local_move_theta_num_; thetai++) {
00126 Eigen::Affine3f trans(Eigen::Translation3f(local_move_x_ / local_move_x_num_ * xi,
00127 local_move_y_ / local_move_y_num_ * yi,
00128 0)
00129 * Eigen::AngleAxisf(local_move_theta_ / local_move_theta_num_ * thetai,
00130 Eigen::Vector3f::UnitZ()));
00131 moved_states.push_back(
00132 FootstepState::Ptr(new FootstepState(in->getLeg(),
00133 in->getPose() * trans,
00134 in->getDimensions(),
00135 in->getResolution())));
00136 }
00137 }
00138 }
00139 return moved_states;
00140 }
00141
00142 std::vector<FootstepGraph::StatePtr>
00143 FootstepGraph::successors(StatePtr target_state)
00144 {
00145 std::vector<Eigen::Affine3f> transformations;
00146 int next_leg;
00147 if (target_state->getLeg() == jsk_footstep_msgs::Footstep::LEFT) {
00148 transformations = successors_from_left_to_right_;
00149 next_leg = jsk_footstep_msgs::Footstep::RIGHT;
00150 }
00151 else if (target_state->getLeg() == jsk_footstep_msgs::Footstep::RIGHT) {
00152 transformations = successors_from_right_to_left_;
00153 next_leg = jsk_footstep_msgs::Footstep::LEFT;
00154 }
00155 else {
00156
00157 }
00158
00159 std::vector<FootstepGraph::StatePtr> ret;
00160 Eigen::Affine3f base_pose = target_state->getPose();
00161 for (size_t i = 0; i < transformations.size(); i++) {
00162 Eigen::Affine3f transform = transformations[i];
00163 FootstepGraph::StatePtr next(new FootstepState(next_leg,
00164 base_pose * transform,
00165 target_state->getDimensions(),
00166 resolution_));
00167 if (use_pointcloud_model_ && !lazy_projection_) {
00168
00169 unsigned int error_state;
00170 next = projectFootstep(next, error_state);
00171 if (!next && localMovement() && error_state == projection_state::close_to_success) {
00172 std::vector<StatePtr> locally_moved_nodes
00173 = localMoveFootstepState(next);
00174 for (size_t j = 0; j < locally_moved_nodes.size(); j++) {
00175 if (transition_limit_) {
00176 if (transition_limit_->check(target_state, locally_moved_nodes[j])) {
00177 ret.push_back(locally_moved_nodes[j]);
00178 }
00179 }
00180 else {
00181 ret.push_back(locally_moved_nodes[j]);
00182 }
00183 }
00184 }
00185 }
00186 if (next) {
00187 if (transition_limit_) {
00188 if (transition_limit_->check(target_state, next)) {
00189 ret.push_back(next);
00190 }
00191 }
00192 else {
00193 ret.push_back(next);
00194 }
00195 }
00196 }
00197 return ret;
00198 }
00199
00200
00201 FootstepState::Ptr FootstepGraph::projectFootstep(FootstepState::Ptr in)
00202 {
00203 unsigned int error_state;
00204 return projectFootstep(in, error_state);
00205 }
00206
00207 FootstepState::Ptr FootstepGraph::projectFootstep(FootstepState::Ptr in,
00208 unsigned int& error_state)
00209 {
00210 FootstepState::Ptr projected_footstep = in->projectToCloud(
00211 *tree_model_,
00212 pointcloud_model_,
00213 grid_search_,
00214 *tree_model_2d_,
00215 pointcloud_model_2d_,
00216 Eigen::Vector3f(0, 0, 1),
00217 error_state,
00218 plane_estimation_outlier_threshold_,
00219 plane_estimation_max_iterations_,
00220 plane_estimation_min_inliers_,
00221 support_check_x_sampling_,
00222 support_check_y_sampling_,
00223 support_check_vertex_neighbor_threshold_);
00224
00225 return projected_footstep;
00226 }
00227
00228 bool FootstepGraph::projectGoal()
00229 {
00230 unsigned int error_state;
00231 FootstepState::Ptr left_projected = projectFootstep(left_goal_state_);
00232 FootstepState::Ptr right_projected = projectFootstep(right_goal_state_);
00233 if (left_projected && right_projected) {
00234 left_goal_state_ = left_projected;
00235 right_goal_state_ = right_projected;
00236 return true;
00237 }
00238 else {
00239 return false;
00240 }
00241 }
00242
00243 bool FootstepGraph::projectStart()
00244 {
00245 unsigned int error_state;
00246 FootstepState::Ptr projected = projectFootstep(start_state_);
00247 if (projected) {
00248 start_state_ = projected;
00249 return true;
00250 }
00251 return false;
00252 }
00253
00254 double footstepHeuristicZero(
00255 SolverNode<FootstepState, FootstepGraph>::Ptr node, FootstepGraph::Ptr graph)
00256 {
00257 return 0;
00258 }
00259
00260 double footstepHeuristicStraight(
00261 SolverNode<FootstepState, FootstepGraph>::Ptr node, FootstepGraph::Ptr graph)
00262 {
00263 FootstepState::Ptr state = node->getState();
00264 FootstepState::Ptr goal = graph->getGoal(state->getLeg());
00265 Eigen::Vector3f state_pos(state->getPose().translation());
00266 Eigen::Vector3f goal_pos(goal->getPose().translation());
00267 return (std::abs((state_pos - goal_pos).norm() / graph->maxSuccessorDistance()));
00268 }
00269
00270 double footstepHeuristicStraightRotation(
00271 SolverNode<FootstepState, FootstepGraph>::Ptr node, FootstepGraph::Ptr graph)
00272 {
00273 FootstepState::Ptr state = node->getState();
00274 FootstepState::Ptr goal = graph->getGoal(state->getLeg());
00275 Eigen::Affine3f transform = state->getPose().inverse() * goal->getPose();
00276 return (std::abs(transform.translation().norm() / graph->maxSuccessorDistance()) +
00277 std::abs(Eigen::AngleAxisf(transform.rotation()).angle()) / graph->maxSuccessorRotation());
00278 }
00279
00280 double footstepHeuristicStepCost(
00281 SolverNode<FootstepState, FootstepGraph>::Ptr node, FootstepGraph::Ptr graph,
00282 double first_rotation_weight,
00283 double second_rotation_weight)
00284 {
00285 FootstepState::Ptr state = node->getState();
00286 FootstepState::Ptr goal = graph->getGoal(state->getLeg());
00287 Eigen::Vector3f goal_pos(goal->getPose().translation());
00288 Eigen::Vector3f diff_pos(goal_pos - state->getPose().translation());
00289 Eigen::Quaternionf first_rot;
00290
00291 first_rot.setFromTwoVectors(state->getPose().matrix().block<3, 3>(0, 0) * Eigen::Vector3f::UnitX(),
00292 diff_pos.normalized());
00293
00294 Eigen::Quaternionf second_rot;
00295 second_rot.setFromTwoVectors(diff_pos.normalized(),
00296 goal->getPose().matrix().block<3, 3>(0, 0) * Eigen::Vector3f::UnitX());
00297
00298 double first_theta = acos(first_rot.w()) * 2;
00299 double second_theta = acos(second_rot.w()) * 2;
00300 if (isnan(first_theta)) {
00301 first_theta = 0;
00302 }
00303 if (isnan(second_theta)) {
00304 second_theta = 0;
00305 }
00306
00307 if (first_theta > M_PI) {
00308 first_theta = 2.0 * M_PI - first_theta;
00309 }
00310 if (second_theta > M_PI) {
00311 second_theta = 2.0 * M_PI - second_theta;
00312 }
00313
00314 return (diff_pos.norm() / graph->maxSuccessorDistance()) + std::abs(diff_pos[2]) / 0.2 +
00315 (first_theta * first_rotation_weight + second_theta * second_rotation_weight) / graph->maxSuccessorRotation();
00316 }
00317
00318 }