terrain_model.cpp
Go to the documentation of this file.
2 
4 
5 #include <pcl/io/pcd_io.h>
6 #include <pcl/kdtree/kdtree_flann.h>
7 
8 #include <vigir_footstep_planning_lib/helper.h>
9 #include <vigir_footstep_planning_lib/math.h>
10 
11 #include <vigir_terrain_classifier/terrain_model.h>
12 
13 
14 
16 {
17 TerrainModel::TerrainModel(const std::string& name)
18  : TerrainModelPlugin(name)
19 {
20 }
21 
22 bool TerrainModel::initialize(const vigir_generic_params::ParameterSet& params)
23 {
24  if (!TerrainModelPlugin::initialize(params))
25  return false;
26 
27  // get foot dimensions
28  getFootSize(nh_, foot_size);
29 
30  // subscribe
31  std::string topic;
32  getParam("terrain_model_topic", topic, std::string("terrain_model"), true);
33  terrain_model_sub = nh_.subscribe(topic, 1, &TerrainModel::setTerrainModel, this);
34 
35  return true;
36 }
37 
38 bool TerrainModel::loadParams(const vigir_generic_params::ParameterSet& params)
39 {
40  if (!TerrainModelPlugin::loadParams(params))
41  return false;
42 
43  params.getParam("foot_contact_support/min_sampling_steps_x", min_sampling_steps_x);
44  params.getParam("foot_contact_support/min_sampling_steps_y", min_sampling_steps_y);
45  params.getParam("foot_contact_support/max_sampling_steps_x", max_sampling_steps_x);
46  params.getParam("foot_contact_support/max_sampling_steps_y", max_sampling_steps_y);
47  params.getParam("foot_contact_support/max_intrusion_z", max_intrusion_z);
48  params.getParam("foot_contact_support/max_ground_clearance", max_ground_clearance);
49  params.getParam("foot_contact_support/minimal_support", minimal_support);
50 
51  return true;
52 }
53 
55 {
56  TerrainModelPlugin::reset();
57 
58  boost::unique_lock<boost::shared_mutex> lock(terrain_model_shared_mutex);
59 
60  if (terrain_model)
61  terrain_model->reset();
62 }
63 
64 bool TerrainModel::isAccessible(const State& s) const
65 {
66  return s.getGroundContactSupport() >= minimal_support;
67 }
68 
69 bool TerrainModel::isAccessible(const State& next, const State& /*current*/) const
70 {
71  return isAccessible(next);
72 }
73 
75 {
76  return terrain_model && terrain_model->hasTerrainModel();
77 }
78 
79 void TerrainModel::setTerrainModel(const vigir_terrain_classifier::TerrainModelMsg::ConstPtr& terrain_model)
80 {
81  boost::unique_lock<boost::shared_mutex> lock(terrain_model_shared_mutex);
82 
83  // update terrain model
84  if (!this->terrain_model)
85  this->terrain_model.reset(new vigir_terrain_classifier::TerrainModel(*terrain_model));
86  else
87  this->terrain_model->fromMsg(*terrain_model);
88 }
89 
91 {
92  boost::shared_lock<boost::shared_mutex> lock(terrain_model_shared_mutex);
93  return terrain_model->getResolution();
94 }
95 
96 bool TerrainModel::getPointWithNormal(const pcl::PointNormal& p_search, pcl::PointNormal& p_result) const
97 {
98  boost::shared_lock<boost::shared_mutex> lock(terrain_model_shared_mutex);
99  return terrain_model->getPointWithNormal(p_search, p_result);
100 }
101 
102 bool TerrainModel::getHeight(double x, double y, double& height) const
103 {
104  boost::shared_lock<boost::shared_mutex> lock(terrain_model_shared_mutex);
105  return terrain_model->getHeight(x, y, height);
106 }
107 
108 bool TerrainModel::getFootContactSupport(const geometry_msgs::Pose& p, double &support, pcl::PointCloud<pcl::PointXYZI>::Ptr checked_positions) const
109 {
110  tf::Pose p_tf;
111  tf::poseMsgToTF(p, p_tf);
112  return getFootContactSupport(p_tf, support, checked_positions);
113 }
114 
115 bool TerrainModel::getFootContactSupport(const tf::Pose& p, double& support, pcl::PointCloud<pcl::PointXYZI>::Ptr checked_positions) const
116 {
117  if (!getFootContactSupport(p, support, min_sampling_steps_x, min_sampling_steps_y, checked_positions))
118  return false;
119 
120  // refinement of solution if needed
121  if (support == 0.0) // collision, no refinement
122  {
123  return true;
124  }
125  else if (support < 0.95)
126  {
127  if (!getFootContactSupport(p, support, max_sampling_steps_x, max_sampling_steps_y, checked_positions))
128  return false;
129  }
130 
131  return true;
132 }
133 
134 bool TerrainModel::getFootContactSupport(const tf::Pose& p, double &support, unsigned int sampling_steps_x, unsigned int sampling_steps_y, pcl::PointCloud<pcl::PointXYZI>::Ptr checked_positions) const
135 {
137  //boost::shared_lock<boost::shared_mutex> lock(terrain_model_shared_mutex);
138 
139  support = 0.0;
140 
141  unsigned int contacts = 0;
142  unsigned int unknown = 0;
143  unsigned int total = 0;
144 
145  tf::Vector3 orig_pos;
146  orig_pos.setZ(0.0);
147 
148  double foot_size_half_x = 0.5*foot_size.x;
149  double foot_size_half_y = 0.5*foot_size.y;
150 
151  double sampling_step_x = foot_size.x/(double)(sampling_steps_x-1);
152  double sampling_step_y = foot_size.y/(double)(sampling_steps_y-1);
153 
154  for (double y = -foot_size_half_y; y <= foot_size_half_y; y+=sampling_step_y)
155  {
156  orig_pos.setY(y);
157  for (double x = -foot_size_half_x; x <= foot_size_half_x; x+=sampling_step_x)
158  {
159  total++;
160 
161  // determine point in world frame and get height at this point
162  orig_pos.setX(x);
163 
164  const tf::Vector3 &trans_pos = p * orig_pos;
165 
166  double height = 0.0;
167  if (!getHeight(trans_pos.getX(), trans_pos.getY(), height))
168  {
169  //ROS_WARN_THROTTLE(1.0, "getFootSupportArea: No height data found at %f/%f", p.getOrigin().getX(), p.getOrigin().getY());
170  unknown++;
171  continue;
172  }
173 
174  // diff heights
175  double diff = trans_pos.getZ()-height;
176 
177  // save evaluated point for visualization
178  if (checked_positions)
179  {
180  pcl::PointXYZI p_checked;
181  p_checked.x = trans_pos.getX();
182  p_checked.y = trans_pos.getY();
183  p_checked.z = trans_pos.getZ();
184  p_checked.intensity = std::abs(diff);
185  checked_positions->push_back(p_checked);
186 
187  //ROS_INFO("%f %f | %f %f | %f", x, y, p.z, height, diff);
188  }
189 
190  // check diff in z
191  if (diff < -max_intrusion_z) // collision -> no support!
192  return true;
193  else if (diff < max_ground_clearance) // ground contact
194  contacts++;
195  }
196  }
197 
198  if (unknown == total)
199  {
200  return false;
201  }
202  else
203  {
205  support = static_cast<double>(contacts)/static_cast<double>(total);
206  return true;
207  }
208 }
209 
210 bool TerrainModel::update3DData(geometry_msgs::Pose& p) const
211 {
212  return terrain_model->update3DData(p);
213 }
214 
215 bool TerrainModel::update3DData(State& s) const
216 {
218  //boost::shared_lock<boost::shared_mutex> lock(terrain_model_shared_mutex);
219  bool result = true;
220 
221  // get z
222  double z = s.getZ();
223  if (!getHeight(s.getX(), s.getY(), z))
224  {
225  //ROS_WARN_THROTTLE(1.0, "No height data found at %f/%f", s.getX(), s.getY());
226  result = false;
227  }
228  else
229  {
230  s.setZ(z);
231  }
232 
233  // get roll and pitch
234  pcl::PointNormal p_n;
235  p_n.x = s.getX();
236  p_n.y = s.getY();
237  p_n.z = s.getZ();
238 
239  if (!getPointWithNormal(p_n, p_n))
240  {
241  //ROS_WARN_THROTTLE(1.0, "No normal data found at %f/%f", s.getX(), s.getY());
242  result = false;
243  }
244  else
245  {
246  s.setNormal(p_n.normal_x, p_n.normal_y, p_n.normal_z);
247  }
248 
249  // determine ground contact support
250  double support = 0.0;
251  if (!getFootContactSupport(s.getPose(), support))
252  {
253  //ROS_WARN_THROTTLE(1.0, "Couldn't determine ground contact support at %f/%f", s.getX(), s.getY());
254  result = false;
255  }
256  else
257  {
258  s.setGroundContactSupport(support);
259  }
260 
261  return result;
262 }
263 }
264 
265 #include <pluginlib/class_list_macros.h>
266 PLUGINLIB_EXPORT_CLASS(vigir_footstep_planning::TerrainModel, vigir_footstep_planning::TerrainModelPlugin)
vigir_terrain_classifier::TerrainModel::Ptr terrain_model
Definition: terrain_model.h:90
bool getHeight(double x, double y, double &height) const override
bool getPointWithNormal(const pcl::PointNormal &p_search, pcl::PointNormal &p_result) const override
TerrainModel(const std::string &name="terrain_model")
bool initialize(const vigir_generic_params::ParameterSet &params=vigir_generic_params::ParameterSet()) override
void setTerrainModel(const vigir_terrain_classifier::TerrainModelMsg::ConstPtr &terrain_model)
bool getFootContactSupport(const geometry_msgs::Pose &p, double &support, pcl::PointCloud< pcl::PointXYZI >::Ptr checked_positions=pcl::PointCloud< pcl::PointXYZI >::Ptr()) const override
bool loadParams(const vigir_generic_params::ParameterSet &params=vigir_generic_params::ParameterSet()) override
bool update3DData(geometry_msgs::Pose &p) const override
boost::shared_mutex terrain_model_shared_mutex
Definition: terrain_model.h:88
double getResolution() const override
bool isTerrainModelAvailable() const override
bool isAccessible(const State &s) const override


vigir_footstep_planning_default_plugins
Author(s): Alexander Stumpf
autogenerated on Sun Nov 17 2019 03:30:01