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
32namespace 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
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
#define float
Definition 16_Level.h:22
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define VAROUT(x)
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
This file offers overloads of toIce() and fromIce() functions for STL container types.
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.
ConfigType dcdSteer(const ConfigType &from, const ConfigType &to, RealType dcdStepSize, CollisionChecker isCollisionFree)
Tries to reach to from from using the given stepsize.