Go to the documentation of this file.00001 #include <vigir_footstep_planning_default_plugins/robot_model/reachability_polygon.h>
00002
00003
00004
00005 namespace vigir_footstep_planning
00006 {
00007 ReachabilityPolygon::ReachabilityPolygon()
00008 : ReachabilityPlugin("reachability_polygon")
00009 , ivpStepRange(nullptr)
00010 {
00011 }
00012
00013 ReachabilityPolygon::~ReachabilityPolygon()
00014 {
00015 if (ivpStepRange)
00016 delete[] ivpStepRange;
00017 }
00018
00019 bool ReachabilityPolygon::loadParams(const ParameterSet& params)
00020 {
00021 if (!ReachabilityPlugin::loadParams(params))
00022 return false;
00023
00024 int num_angle_bins;
00025 params.getParam("collision_check/cell_size", cell_size);
00026 params.getParam("collision_check/num_angle_bins", num_angle_bins);
00027 angle_bin_size = 2.0*M_PI / static_cast<double>(num_angle_bins);
00028
00029
00030 std::vector<std::pair<int, int> > step_range;
00031 XmlRpc::XmlRpcValue step_range_x;
00032 XmlRpc::XmlRpcValue step_range_y;
00033
00034 if (!params.getParam("step_range/x", step_range_x) || !params.getParam("step_range/y", step_range_y))
00035 {
00036 ROS_ERROR("Can't initialize ReachabilityPolygon due to missing step_range in parameter set!");
00037 return false;
00038 }
00039
00040 assert((step_range_x.size() == step_range_y.size()) && (step_range_x.size() > 0));
00041
00042
00043 step_range.clear();
00044 step_range.reserve(step_range_x.size());
00045
00046 for (int i = 0; i < step_range_x.size(); i++)
00047 {
00048 double x = static_cast<double>(step_range_x[i]);
00049 double y = static_cast<double>(step_range_y[i]);
00050
00051 step_range.push_back(std::pair<int, int>(disc_val(x, cell_size), disc_val(y, cell_size)));
00052 }
00053
00054
00055 params.getParam("max_step_range/x", max_step_range_x);
00056 params.getParam("max_step_range/y", max_step_range_y);
00057 params.getParam("max_step_range/yaw", max_step_range_yaw);
00058
00059 params.getParam("max_step_range/inv_x", max_step_range_inv_x);
00060 params.getParam("max_step_range/inv_y", max_step_range_inv_y);
00061 params.getParam("max_step_range/inv_yaw", max_step_range_inv_yaw);
00062
00063 params.getParam("max_step_range/width", max_step_range_width_sq);
00064 max_step_range_width_sq = max_step_range_width_sq*max_step_range_width_sq;
00065
00066 int max_step_range_x_disc = disc_val(max_step_range_x, cell_size);
00067 int max_step_range_y_disc = disc_val(max_step_range_y, cell_size);
00068
00069 int max_step_range_inv_x_disc = disc_val(max_step_range_inv_x, cell_size);
00070 int max_step_range_inv_y_disc = disc_val(max_step_range_inv_y, cell_size);
00071
00072 step_range_size_x = max_step_range_x_disc - max_step_range_inv_x_disc + 1;
00073 step_range_size_y = max_step_range_y_disc - max_step_range_inv_y_disc + 1;
00074 step_range_size = step_range_size_x * step_range_size_y;
00075
00076 if (ivpStepRange)
00077 delete[] ivpStepRange;
00078 ivpStepRange = new bool[step_range_size];
00079
00080
00081 ROS_INFO("Reachability Polygon:");
00082 std::string msg;
00083 for (int y = max_step_range_inv_y_disc; y <= max_step_range_y_disc; y++)
00084 {
00085 msg += boost::lexical_cast<std::string>(y) + ": ";
00086 for (int x = max_step_range_inv_x_disc; x <= max_step_range_x_disc; x++)
00087 {
00088 ivpStepRange[(y - max_step_range_inv_y_disc) * step_range_size_x + (x - max_step_range_inv_x_disc)] = pointWithinPolygon(x, y, step_range);
00089 msg += pointWithinPolygon(x, y, step_range) ? "+ " : "- ";
00090 }
00091 ROS_INFO("%s", msg.c_str());
00092 msg.clear();
00093 }
00094
00095 return true;
00096 }
00097
00098 bool ReachabilityPolygon::isReachable(const State& current, const State& next) const
00099 {
00100 if (current.getLeg() == next.getLeg())
00101 return false;
00102
00103 if (euclidean_distance_sq(current.getX(), current.getY(), next.getX(), next.getY()) > max_step_range_width_sq)
00104 return false;
00105
00106
00107 tf::Transform step = current.getPose().inverse() * next.getPose();
00108 double dx = step.getOrigin().x();
00109 double dy = step.getOrigin().y();
00110 double dyaw = angles::shortest_angular_distance(current.getYaw(), next.getYaw());
00111
00112
00113 if (current.getLeg() == LEFT)
00114 {
00115 dy = -dy;
00116 dyaw = -dyaw;
00117 }
00118
00119
00120 dx = pround(dx, cell_size);
00121 dy = pround(dy, cell_size);
00122 dyaw = pround(dyaw, angle_bin_size);
00123
00124
00125 if (dx > max_step_range_x || dx < max_step_range_inv_x)
00126 return false;
00127
00128 if (dy > max_step_range_y || dy < max_step_range_inv_y)
00129 return false;
00130
00131 if (dyaw > max_step_range_yaw || dyaw < max_step_range_inv_yaw)
00132 return false;
00133
00134 int footstep_x = floor((dx-max_step_range_inv_x) / cell_size);
00135 int footstep_y = floor((dy-max_step_range_inv_y) / cell_size);
00136
00137 assert((footstep_x + footstep_y * step_range_size_x) < step_range_size);
00138
00139
00140 if (!ivpStepRange[footstep_x + footstep_y * step_range_size_x])
00141 return false;
00142
00143 return true;
00144 }
00145 }
00146
00147 #include <pluginlib/class_list_macros.h>
00148 PLUGINLIB_EXPORT_CLASS(vigir_footstep_planning::ReachabilityPolygon, vigir_footstep_planning::ReachabilityPlugin)