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 #include <jsk_footstep_msgs/FootstepArray.h>
00036 #include "jsk_footstep_planner/footstep_graph.h"
00037 #include "jsk_footstep_planner/astar_solver.h"
00038 #include "jsk_footstep_planner/footstep_astar_solver.h"
00039 #include <time.h>
00040 #include <boost/random.hpp>
00041 #include <interactive_markers/tools.h>
00042 #include <interactive_markers/interactive_marker_server.h>
00043 #include <jsk_recognition_utils/pcl_conversion_util.h>
00044 #include <jsk_rviz_plugins/OverlayText.h>
00045 #include <boost/format.hpp>
00046 #include <jsk_recognition_utils/pcl_conversion_util.h>
00047
00048 using namespace jsk_footstep_planner;
00049
00050 const Eigen::Vector3f footstep_size(0.2, 0.1, 0.000001);
00051 const Eigen::Vector3f resolution(0.05, 0.05, 0.08);
00052 ros::Publisher pub_goal, pub_path, pub_text, pub_close_list, pub_open_list;
00053 FootstepGraph::Ptr graph;
00054
00055 void profile(FootstepAStarSolver<FootstepGraph>& solver, FootstepGraph::Ptr graph)
00056 {
00057 ROS_INFO("open list: %lu", solver.getOpenList().size());
00058 ROS_INFO("close list: %lu", solver.getCloseList().size());
00059 FootstepAStarSolver<FootstepGraph>::OpenList open_list = solver.getOpenList();
00060 }
00061
00062 void plan(const Eigen::Affine3f& goal_center,
00063 FootstepGraph::Ptr graph, ros::Publisher& pub_path,
00064 ros::Publisher& pub_goal,
00065 Eigen::Vector3f footstep_size)
00066 {
00067 FootstepState::Ptr left_goal(new FootstepState(jsk_footstep_msgs::Footstep::LEFT,
00068 goal_center * Eigen::Translation3f(0, 0.1, 0),
00069 footstep_size,
00070 resolution));
00071 FootstepState::Ptr right_goal(new FootstepState(jsk_footstep_msgs::Footstep::RIGHT,
00072 goal_center * Eigen::Translation3f(0, -0.1, 0),
00073 footstep_size,
00074 resolution));
00075
00076 graph->setGoalState(left_goal, right_goal);
00077 if (!graph->projectGoal()) {
00078 ROS_ERROR("Failed to project goal");
00079 return;
00080 }
00081
00082 jsk_footstep_msgs::FootstepArray ros_goal;
00083 ros_goal.header.frame_id = "odom";
00084 ros_goal.header.stamp = ros::Time::now();
00085 ros_goal.footsteps.push_back(*graph->getGoal(jsk_footstep_msgs::Footstep::LEFT)->toROSMsg());
00086 ros_goal.footsteps.push_back(*graph->getGoal(jsk_footstep_msgs::Footstep::RIGHT)->toROSMsg());
00087 pub_goal.publish(ros_goal);
00088
00089
00090
00091 FootstepAStarSolver<FootstepGraph> solver(graph, 100, 100, 100);
00092
00093
00094 solver.setHeuristic(boost::bind(&footstepHeuristicStepCost, _1, _2, 1.0, 0.1));
00095 solver.setProfileFunction(&profile);
00096 ros::WallTime start_time = ros::WallTime::now();
00097 std::vector<SolverNode<FootstepState, FootstepGraph>::Ptr> path = solver.solve(ros::WallDuration(2000.0));
00098 ros::WallTime end_time = ros::WallTime::now();
00099 std::cout << "took " << (end_time - start_time).toSec() << " sec" << std::endl;
00100 std::cout << "path: " << path.size() << std::endl;
00101 if (path.size() == 0) {
00102 ROS_ERROR("Failed to plan path");
00103 return;
00104 }
00105 jsk_footstep_msgs::FootstepArray ros_path;
00106 ros_path.header.frame_id = "odom";
00107 ros_path.header.stamp = ros::Time::now();
00108 for (size_t i = 0; i < path.size(); i++) {
00109 ros_path.footsteps.push_back(*path[i]->getState()->toROSMsg());
00110 }
00111 pub_path.publish(ros_path);
00112 pcl::PointCloud<pcl::PointXYZ> close_cloud, open_cloud;
00113 solver.openListToPointCloud<pcl::PointXYZ>(open_cloud);
00114 solver.closeListToPointCloud<pcl::PointXYZ>(close_cloud);
00115 sensor_msgs::PointCloud2 ros_close_cloud, ros_open_cloud;
00116 pcl::toROSMsg(close_cloud, ros_close_cloud);
00117 ros_close_cloud.header.stamp = ros::Time::now();
00118 ros_close_cloud.header.frame_id = "odom";
00119 pub_close_list.publish(ros_close_cloud);
00120 pcl::toROSMsg(open_cloud, ros_open_cloud);
00121 ros_open_cloud.header.stamp = ros::Time::now();
00122 ros_open_cloud.header.frame_id = "odom";
00123 pub_open_list.publish(ros_open_cloud);
00124 }
00125
00126
00127 void processFeedback(
00128 const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00129 {
00130 if (feedback->event_type != visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP) {
00131 return;
00132 }
00133 Eigen::Affine3f new_pose;
00134 tf::poseMsgToEigen(feedback->pose, new_pose);
00135 ros::WallTime start = ros::WallTime::now();
00136 plan(new_pose, graph, pub_path, pub_goal, footstep_size);
00137 ros::WallTime end = ros::WallTime::now();
00138 jsk_rviz_plugins::OverlayText text;
00139 text.bg_color.a = 0.0;
00140 text.fg_color.a = 1.0;
00141 text.fg_color.r = 25 / 255.0;
00142 text.fg_color.g = 1.0;
00143 text.fg_color.b = 250 / 255.0;
00144 text.line_width = 2;
00145 text.top = 10;
00146 text.left = 10;
00147 text.text_size = 24;
00148 text.width = 600;
00149 text.height = 100;
00150 text.text = (boost::format("Planning took %f sec") % (end - start).toSec()).str();
00151 pub_text.publish(text);
00152 }
00153
00154 pcl::PointCloud<pcl::PointNormal>::Ptr
00155 generateCloudSlope()
00156 {
00157 pcl::PointCloud<pcl::PointNormal>::Ptr gen_cloud(new pcl::PointCloud<pcl::PointNormal>);
00158 for (double y = -0.5; y < 0.5; y = y + 0.01) {
00159 for (double x = -1.0; x < 0.5; x = x + 0.01) {
00160 pcl::PointNormal p;
00161 p.x = x;
00162 p.y = y;
00163 gen_cloud->points.push_back(p);
00164 }
00165 for (double x = 0.5; x < 5.0; x = x + 0.01) {
00166 pcl::PointNormal p;
00167 p.x = x;
00168 p.y = y;
00169 p.z = 0.2 * x - 0.5 * 0.2;
00170 gen_cloud->points.push_back(p);
00171 }
00172 }
00173 return gen_cloud;
00174 }
00175
00176 pcl::PointCloud<pcl::PointNormal>::Ptr
00177 generateCloudFlat()
00178 {
00179 pcl::PointCloud<pcl::PointNormal>::Ptr gen_cloud(new pcl::PointCloud<pcl::PointNormal>);
00180 for (double y = -2; y < 2; y = y + 0.01) {
00181 for (double x = -2; x < 2; x = x + 0.01) {
00182 pcl::PointNormal p;
00183 p.x = x;
00184 p.y = y;
00185 gen_cloud->points.push_back(p);
00186 }
00187 }
00188 return gen_cloud;
00189 }
00190
00191 pcl::PointCloud<pcl::PointNormal>::Ptr
00192 generateCloudHills()
00193 {
00194 const double height = 0.1;
00195 pcl::PointCloud<pcl::PointNormal>::Ptr gen_cloud(new pcl::PointCloud<pcl::PointNormal>);
00196 for (double y = -2; y < 2; y = y + 0.01) {
00197 for (double x = -2; x < 2; x = x + 0.01) {
00198 pcl::PointNormal p;
00199 p.x = x;
00200 p.y = y;
00201 p.z = height * sin(x * 2) * sin(y * 2);
00202 gen_cloud->points.push_back(p);
00203 }
00204 }
00205 return gen_cloud;
00206 }
00207
00208 pcl::PointCloud<pcl::PointNormal>::Ptr
00209 generateCloudStairs()
00210 {
00211 const double height = 0.1;
00212 pcl::PointCloud<pcl::PointNormal>::Ptr gen_cloud(new pcl::PointCloud<pcl::PointNormal>);
00213 for (double y = -2; y < 2; y = y + 0.01) {
00214 for (double x = -1; x < 0; x = x + 0.01) {
00215 pcl::PointNormal p;
00216 p.x = x;
00217 p.y = y;
00218 p.z = 0;
00219 gen_cloud->points.push_back(p);
00220 }
00221 for (double x = 0; x < 5; x = x + 0.01) {
00222 pcl::PointNormal p;
00223 p.x = x;
00224 p.y = y;
00225 p.z = floor(x * 4) * 0.1;
00226 gen_cloud->points.push_back(p);
00227 }
00228 }
00229 return gen_cloud;
00230 }
00231
00232
00233 int main(int argc, char** argv)
00234 {
00235 ros::init(argc, argv, "foootstep_planning_2d");
00236 ros::NodeHandle nh("~");
00237 ros::Publisher pub_start = nh.advertise<jsk_footstep_msgs::FootstepArray>("start", 1, true);
00238 pub_goal = nh.advertise<jsk_footstep_msgs::FootstepArray>("goal", 1, true);
00239 pub_path = nh.advertise<jsk_footstep_msgs::FootstepArray>("path", 1, true);
00240 pub_text = nh.advertise<jsk_rviz_plugins::OverlayText>("text", 1, true);
00241 ros::Publisher pub_cloud
00242 = nh.advertise<sensor_msgs::PointCloud2>("cloud", 1, true);
00243 pub_close_list
00244 = nh.advertise<sensor_msgs::PointCloud2>("close_list", 1, true);
00245 pub_open_list
00246 = nh.advertise<sensor_msgs::PointCloud2>("open_list", 1, true);
00247 boost::mt19937 rng( static_cast<unsigned long>(time(0)) );
00248 boost::uniform_real<> xyrange(-3.0,3.0);
00249 boost::variate_generator< boost::mt19937, boost::uniform_real<> > pos_rand(rng, xyrange);
00250 boost::uniform_real<> trange(0, 2 * M_PI);
00251 boost::variate_generator< boost::mt19937, boost::uniform_real<> > rot_rand(rng, trange);
00252 pcl::PointCloud<pcl::PointNormal>::Ptr cloud;
00253 std::string model;
00254 nh.param("model", model, std::string("flat"));
00255 if (model == "flat") {
00256 cloud = generateCloudFlat();
00257 }
00258 else if (model == "slope") {
00259 cloud = generateCloudSlope();
00260 }
00261 else if (model == "hills") {
00262 cloud = generateCloudHills();
00263 }
00264 else if (model == "stairs") {
00265 cloud = generateCloudStairs();
00266 }
00267 graph.reset(new FootstepGraph(resolution, true, true, true));
00268 sensor_msgs::PointCloud2 ros_cloud;
00269 pcl::toROSMsg(*cloud, ros_cloud);
00270 ros_cloud.header.frame_id = "odom";
00271 ros_cloud.header.stamp = ros::Time::now();
00272 pub_cloud.publish(ros_cloud);
00273 graph->setPointCloudModel(cloud);
00274
00275
00276 std::vector<Eigen::Affine3f> successors;
00277 successors.push_back(affineFromXYYaw(0, -0.2, 0));
00278 successors.push_back(affineFromXYYaw(0, -0.3, 0));
00279 successors.push_back(affineFromXYYaw(0, -0.15, 0));
00280 successors.push_back(affineFromXYYaw(0.2, -0.2, 0));
00281 successors.push_back(affineFromXYYaw(0.25, -0.2, 0));
00282 successors.push_back(affineFromXYYaw(0.3, -0.2, 0));
00283 successors.push_back(affineFromXYYaw(0.1, -0.2, 0));
00284 successors.push_back(affineFromXYYaw(-0.1, -0.2, 0));
00285 successors.push_back(affineFromXYYaw(0, -0.2, 0.17));
00286 successors.push_back(affineFromXYYaw(0, -0.3, 0.17));
00287 successors.push_back(affineFromXYYaw(0.2, -0.2, 0.17));
00288 successors.push_back(affineFromXYYaw(0.25, -0.2, 0.17));
00289 successors.push_back(affineFromXYYaw(0.1, -0.2, 0.17));
00290 successors.push_back(affineFromXYYaw(0, -0.2, -0.17));
00291 successors.push_back(affineFromXYYaw(0, -0.3, -0.17));
00292 successors.push_back(affineFromXYYaw(0.2, -0.2, -0.17));
00293 successors.push_back(affineFromXYYaw(0.25, -0.2, -0.17));
00294 successors.push_back(affineFromXYYaw(0.1, -0.2, -0.17));
00295 FootstepState::Ptr start(new FootstepState(jsk_footstep_msgs::Footstep::LEFT,
00296 Eigen::Affine3f::Identity(),
00297 footstep_size,
00298 resolution));
00299 graph->setStartState(start);
00300 graph->setBasicSuccessors(successors);
00301 jsk_footstep_msgs::FootstepArray ros_start;
00302 ros_start.header.frame_id = "odom";
00303 ros_start.header.stamp = ros::Time::now();
00304 ros_start.footsteps.push_back(*start->toROSMsg());
00305 pub_start.publish(ros_start);
00306 interactive_markers::InteractiveMarkerServer server("footstep_projection_demo");
00307
00308 visualization_msgs::InteractiveMarker int_marker;
00309 int_marker.header.frame_id = "/odom";
00310 int_marker.header.stamp=ros::Time::now();
00311 int_marker.name = "footstep marker";
00312
00313 visualization_msgs::InteractiveMarkerControl control;
00314
00315 control.orientation.w = 1;
00316 control.orientation.x = 1;
00317 control.orientation.y = 0;
00318 control.orientation.z = 0;
00319
00320
00321 control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00322 int_marker.controls.push_back(control);
00323
00324 control.orientation.w = 1;
00325 control.orientation.x = 0;
00326 control.orientation.y = 1;
00327 control.orientation.z = 0;
00328 control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00329 int_marker.controls.push_back(control);
00330 control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00331 int_marker.controls.push_back(control);
00332
00333 control.orientation.w = 1;
00334 control.orientation.x = 0;
00335 control.orientation.y = 0;
00336 control.orientation.z = 1;
00337
00338
00339 control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00340 int_marker.controls.push_back(control);
00341 server.insert(int_marker, &processFeedback);
00342 server.applyChanges();
00343
00344 plan(Eigen::Affine3f::Identity() * Eigen::Translation3f(1.7, 0.0, 0), graph, pub_path, pub_goal, footstep_size);
00345
00346 ros::spin();
00347 return 0;
00348 }