CollisionCheckUtil.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package RobotComponents
19  * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
20  * @date 2015
21  * @copyright http://www.gnu.org/licenses/gpl.txt
22  * GNU General Public License
23  */
24 #pragma once
25 
26 #include <optional>
27 
28 #include <Eigen/Core>
29 
31 
32 namespace armarx
33 {
34  /**
35  * @brief Tries to reach to from from using the given stepsize.
36  * @param from The starting point.
37  * @param to The target point.
38  * @param dcdStepSize The used stepsize.
39  * @param isCollisionFree The collision checker used to test configuration for collision.
40  * @return Returns the point p that maximizes distance(from,p) while the line(from, p)
41  * is collision free at all points with a distance of k * dcdStepSize from from.
42  * If no such point is reachable exactly from is returned.
43  * If to is reachable exactly to is returned.
44  */
45  template <class RealType, class CollisionChecker, class ConfigType>
46  ConfigType
47  dcdSteer(const ConfigType& from,
48  const ConfigType& to,
49  RealType dcdStepSize,
50  CollisionChecker isCollisionFree)
51  {
53  ARMARX_CHECK_EXPRESSION(from.size() == to.size());
54  const auto size = static_cast<long int>(from.size()); //eigen wants long int
55  //get eigen views
56  Eigen::Map<const EigenVector> eFrom{from.data(), size};
57  Eigen::Map<const EigenVector> eTo{to.data(), size};
58 
59  EigenVector step = eTo - eFrom;
60  const auto length = step.norm();
61  step *= dcdStepSize / length; // if length == 0 this values does not get used
62 
63  //will truncate in most cases => we will need to check the destination step for collision
64  ARMARX_CHECK_EXPRESSION(length / dcdStepSize < std::numeric_limits<RealType>::infinity());
65  ARMARX_CHECK_EXPRESSION(length / dcdStepSize <
66  static_cast<RealType>(std::numeric_limits<std::size_t>::max()));
67  const std::size_t stepsToTake = static_cast<std::size_t>(length / dcdStepSize);
68 
69  ConfigType stepToCheck(from);
70  ARMARX_CHECK_EXPRESSION(stepToCheck.size() == from.size());
71  Eigen::Map<EigenVector> eStepToCheck{stepToCheck.data(), size};
72  std::size_t stepsTaken = 0;
73 
74  for (; stepsTaken < stepsToTake; ++stepsTaken)
75  {
76  eStepToCheck += step;
77 
78  if (!isCollisionFree(stepToCheck))
79  {
80  if (0 == stepsTaken)
81  {
82  //could not move!
83  //return an exact copy
84  return from;
85  }
86 
87  eStepToCheck -= step;
88  return stepToCheck;
89  }
90  }
91 
92  ARMARX_CHECK_EXPRESSION(stepsTaken == stepsToTake);
93 
94  //check to
95  if (isCollisionFree(to))
96  {
97  //return an exact copy
98  return to;
99  }
100 
101  //to has collision or was not reached
102  return stepToCheck;
103  }
104 
105  //startCfg is assumed to be collision free
106  /**
107  * @brief Returns whether the line startCfg to to is collision free.
108  * @param from The config to startCfg from. (startCfg is assumed to be collision free.
109  * @param to The config to reach
110  * @param dcdStepSize The dcd step size
111  * @param isCollisionFree The collision checker returning true, if a config is collision free.
112  * @param toIsCollisionFree Whether to is collision free
113  * @return Whether the line startCfg to to is collision free.
114  */
115  template <
116  class RealType,
117  class CollisionChecker,
118  class ConfigType,
119  class Distance = std::function<float(Eigen::VectorXf, Eigen::VectorXf)>,
120  class Interpolate = std::function<Eigen::VectorXf(Eigen::VectorXf, Eigen::VectorXf, float)>>
121  bool
123  const ConfigType& from,
124  const ConfigType& to,
125  RealType dcdStepSize,
126  CollisionChecker isCollisionFree,
127  bool toIsCollisionFree = true,
128  const std::optional<Distance>& distanceLambda = std::optional<Distance>(),
129  const std::optional<Interpolate>& interpolationLambda = std::optional<Interpolate>(),
130  std::vector<ConfigType>* resultPath = NULL)
131  {
132  if (!(toIsCollisionFree || isCollisionFree(to)))
133  {
134  return false;
135  }
136 
137  using EigenVector = Eigen::Matrix<RealType, Eigen::Dynamic, 1>;
138  ARMARX_CHECK_EXPRESSION(from.size() == to.size());
139  const auto size = static_cast<long int>(from.size()); //eigen wants long int
140  //get eigen views
141  Eigen::Map<const EigenVector> eFrom{from.data(), size};
142  Eigen::Map<const EigenVector> eTo{to.data(), size};
143  EigenVector connecting = eTo - eFrom;
144  std::vector<float> tmp(size);
145  Eigen::Map<EigenVector> eTmp{tmp.data(), size};
146  float distanceFromTo;
147  if (distanceLambda)
148  {
149  distanceFromTo = (*distanceLambda)(eFrom, eTo);
150  }
151  else
152  {
153  distanceFromTo = connecting.norm();
154  }
155  ARMARX_INFO << deactivateSpam(1) << VAROUT(dcdStepSize) << VAROUT(distanceFromTo)
156  << VAROUT(eFrom) << VAROUT(eTo);
157  if (distanceFromTo <= dcdStepSize)
158  {
159  if (resultPath)
160  {
161  resultPath->push_back(to);
162  }
163  //since to is collision free
164  return true;
165  }
166 
167  float dcdAsDistanceFactor = dcdStepSize / distanceFromTo;
168 
169  float checkedStepFactor;
170  float betweenStepFactor;
171  std::size_t stepsToCheck = 1;
172 
173  do
174  {
175  betweenStepFactor = 1.f / stepsToCheck;
176  checkedStepFactor = betweenStepFactor / 2.f;
177 
178  float factor = checkedStepFactor;
179 
180  for (std::size_t step = 0; step < stepsToCheck; ++step, factor += betweenStepFactor)
181  {
182  if (interpolationLambda)
183  {
184  eTmp = (*interpolationLambda)(eFrom, eTo, factor);
185  }
186  else
187  {
188  eTmp = eFrom + factor * connecting;
189  }
190  if (!isCollisionFree(tmp))
191  {
192  return false;
193  }
194  }
195  if (resultPath)
196  {
197  resultPath->push_back(tmp);
198  }
199  //increment steps
200  stepsToCheck = stepsToCheck << 1;
201  } while (checkedStepFactor > dcdAsDistanceFactor);
202 
203  //checked everything and no collision
204  return true;
205  }
206 } // namespace armarx
armarx::dcdIsPathCollisionFree
bool dcdIsPathCollisionFree(const ConfigType &from, const ConfigType &to, RealType dcdStepSize, CollisionChecker isCollisionFree, bool toIsCollisionFree=true, const std::optional< Distance > &distanceLambda=std::optional< Distance >(), const std::optional< Interpolate > &interpolationLambda=std::optional< Interpolate >(), std::vector< ConfigType > *resultPath=NULL)
Returns whether the line startCfg to to is collision free.
Definition: CollisionCheckUtil.h:122
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
armarx::dcdSteer
ConfigType dcdSteer(const ConfigType &from, const ConfigType &to, RealType dcdStepSize, CollisionChecker isCollisionFree)
Tries to reach to from from using the given stepsize.
Definition: CollisionCheckUtil.h:47
max
T max(T t1, T t2)
Definition: gdiam.h:51
ExpressionException.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
float
#define float
Definition: 16_Level.h:22
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
Eigen::Matrix
Definition: EigenForwardDeclarations.h:27
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27