reachability_polygon.cpp
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   // step range
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   // load step range
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   // get step range limits
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   // compute reachability polygon
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   // reconstruct step primitive
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   // adjust for the left foot
00113   if (current.getLeg() == LEFT)
00114   {
00115     dy = -dy;
00116     dyaw = -dyaw;
00117   }
00118 
00119   // consider discretization error
00120   dx = pround(dx, cell_size);
00121   dy = pround(dy, cell_size);
00122   dyaw = pround(dyaw, angle_bin_size);
00123 
00124   // check if footstep_x is not within the executable range
00125   if (dx > max_step_range_x || dx < max_step_range_inv_x)
00126     return false;
00127   // check if footstep_y is not within the executable range
00128   if (dy > max_step_range_y || dy < max_step_range_inv_y)
00129     return false;
00130   // check if stance_yaw_diff is not within the executable range
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   // check reachability polygon
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)


vigir_footstep_planning_default_plugins
Author(s): Alexander Stumpf
autogenerated on Fri Apr 7 2017 02:59:40