CostmapBuilder.cpp
Go to the documentation of this file.
1 /**
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @author Fabian Reister ( fabian dot reister at kit dot edu )
17  * @date 2022
18  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19  * GNU General Public License
20  */
21 
22 #include "CostmapBuilder.h"
23 
24 #include <cstddef>
25 #include <limits>
26 
27 #include <VirtualRobot/CollisionDetection/CollisionChecker.h>
28 #include <VirtualRobot/Robot.h>
29 #include <VirtualRobot/SceneObjectSet.h>
30 
34 
39 
41 {
42 
43 
45  const VirtualRobot::SceneObjectSetPtr& obstacles,
46  const std::vector<VirtualRobot::RobotPtr>& articulatedObjects,
47  const Costmap::Parameters& parameters,
48  const std::string& robotCollisonModelName) :
49  robot(robot),
50  obstacles(obstacles),
52  parameters(parameters),
53  robotCollisionModelName(robotCollisonModelName)
54  {
55  ARMARX_CHECK_NOT_NULL(robot) << "Robot must be set";
56  ARMARX_CHECK_NOT_NULL(obstacles);
57  ARMARX_CHECK(robot->hasRobotNode(robotCollisionModelName));
58  }
59 
60  Costmap
62  {
63 
64  const auto sceneBounds = computeSceneBounds(obstacles, articulatedObjects, init, parameters.sceneBoundsMargin);
65  const auto grid = createUniformGrid(sceneBounds, parameters);
66 
67  ARMARX_VERBOSE << "Creating grid";
68  Costmap costmap(grid, parameters, sceneBounds);
69 
70  ARMARX_VERBOSE << "Filling grid with size (" << costmap.getGrid().rows() << "/"
71  << costmap.getGrid().cols() << ")";
72  fillGridCosts(costmap);
73  ARMARX_VERBOSE << "Filled grid";
74 
75  initializeMask(costmap);
76  ARMARX_VERBOSE << "Initialized mask";
77 
78  return costmap;
79  }
80 
81  void
82  CostmapBuilder::initializeMask(Costmap& costmap)
83  {
84  costmap.mask = costmap.grid.array() > 0.F;
85 
86  ARMARX_VERBOSE << "Initializing mask: Fraction of valid elements: "
87  << costmap.mask->cast<float>().sum() / costmap.mask->size();
88  }
89 
90  Eigen::MatrixXf
92  const Costmap::Parameters& parameters)
93  {
95 
96  ARMARX_VERBOSE << "Scene bounds are " << sceneBounds.min << " and " << sceneBounds.max;
97 
98  //+1 for explicit rounding up
99  size_t c_x = (sceneBounds.max.x() - sceneBounds.min.x()) / parameters.cellSize + 1;
100  size_t c_y = (sceneBounds.max.y() - sceneBounds.min.y()) / parameters.cellSize + 1;
101 
102  ARMARX_VERBOSE << "Grid size: " << c_x << ", " << c_y;
103 
104  ARMARX_VERBOSE << "Resetting grid";
105  Eigen::MatrixXf grid(c_x, c_y);
106  grid.setZero();
107 
108  return grid;
109  }
110 
111  float
112  CostmapBuilder::computeCost(const Costmap::Position& position,
113  VirtualRobot::RobotPtr& collisionRobot,
114  const VirtualRobot::CollisionModelPtr& robotCollisionModel)
115  {
116  ARMARX_TRACE;
117  ARMARX_CHECK_NOT_NULL(collisionRobot);
118  ARMARX_CHECK_NOT_NULL(robotCollisionModel);
119  ARMARX_CHECK_NOT_NULL(VirtualRobot::CollisionChecker::getGlobalCollisionChecker());
120  ARMARX_CHECK_NOT_NULL(obstacles);
121  ARMARX_CHECK_GREATER(obstacles->getSize(), 0);
122 
123  const core::Pose globalPose(Eigen::Translation3f(conv::to3D(position)));
124  collisionRobot->setGlobalPose(globalPose.matrix());
125 
126  // distance to non-articulated objects
127  const float distanceNonArticulated =
128  VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance(
129  robotCollisionModel, obstacles);
130 
131 
132  float distanceArticulatedMin = std::numeric_limits<float>::max();
133  for(const auto& articulatedObject : articulatedObjects)
134  {
135  for(const auto& colModel : articulatedObject->getCollisionModels())
136  {
137  const float distanceArticulated = VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance(robotCollisionModel, colModel);
138  distanceArticulatedMin = std::min(distanceArticulated, distanceArticulatedMin);
139  }
140  }
141 
142  return std::min(distanceNonArticulated, distanceArticulatedMin);
143 
144 
145  // Eigen::Vector3f P1;
146  // Eigen::Vector3f P2;
147  // int id1, id2;
148 
149  // float minDistance = std::numeric_limits<float>::max();
150 
151  // // TODO omp...
152  // for (size_t i = 0; i < obstacles->getSize(); i++)
153  // {
154  // // cheap collision check
155  // // VirtualRobot::BoundingBox obstacleBbox =
156  // // obstacles->getSceneObject(i)->getCollisionModel()->getBoundingBox(true);
157  // // if (not intersects(robotBbox, obstacleBbox))
158  // // {
159  // // continue;
160  // // }
161 
162  // // precise collision check
163  // const float dist =
164  // VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance(
165  // robotCollisionModel,
166  // obstacles->getSceneObject(i)->getCollisionModel(),
167  // P1,
168  // P2,
169  // &id1,
170  // &id2);
171 
172  // // check if objects collide
173  // if ((dist <= parameters.cellSize / 2) or
174  // VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->checkCollision(
175  // robotCollisionModel, obstacles->getSceneObject(i)->getCollisionModel()))
176  // {
177  // minDistance = 0;
178  // break;
179  // }
180 
181  // minDistance = std::min(minDistance, dist);
182  // }
183  // // return n->position.x() >= sceneBounds.min.x() && n->position.x() <= sceneBounds.max.x() &&
184  // // n->position.y() >= sceneBounds.min.y() && n->position.y() <= sceneBounds.max.y();
185 
186  // return minDistance;
187  }
188 
189  void
190  CostmapBuilder::fillGridCosts(Costmap& costmap)
191  {
192 
193  VirtualRobot::RobotPtr collisionRobot;
194  VirtualRobot::CollisionModelPtr robotCollisionModel;
195 
196  const std::size_t c_x = costmap.grid.rows();
197  const std::size_t c_y = costmap.grid.cols();
198 
199  robot->setUpdateVisualization(false);
200 
201 #pragma omp parallel for schedule(static) private(collisionRobot, \
202  robotCollisionModel) default(shared)
203  for (unsigned int x = 0; x < c_x; x++)
204  {
205  // initialize if needed
206  if (collisionRobot == nullptr)
207  {
208 #pragma omp critical
209  {
210  ARMARX_DEBUG << "Copying robot";
211  ARMARX_CHECK_NOT_NULL(robot);
212  collisionRobot =
213  robot->clone("collision_robot_" + std::to_string(omp_get_thread_num()));
214 
215  // replace the standard collision model by our custom one
216  collisionRobot->setPrimitiveApproximationModel({"navigation"}, false);
217 
218  collisionRobot->setUpdateVisualization(false);
219  ARMARX_DEBUG << "Copying done";
220  }
221 
222  ARMARX_CHECK_NOT_NULL(collisionRobot);
223  ARMARX_CHECK(collisionRobot->hasRobotNode(robotCollisionModelName));
224 
225  ARMARX_CHECK(collisionRobot);
226  const auto collisionRobotNode =
227  collisionRobot->getRobotNode(robotCollisionModelName);
228  ARMARX_CHECK_NOT_NULL(collisionRobotNode);
229 
230  robotCollisionModel = collisionRobotNode->getCollisionModel();
231  ARMARX_CHECK(robotCollisionModel) << "Collision model not available. "
232  "Make sure that you load the robot correctly!";
233  }
234 
235  ARMARX_CHECK_NOT_NULL(collisionRobot);
236  ARMARX_CHECK_NOT_NULL(robotCollisionModel);
237 
238  for (unsigned int y = 0; y < c_y; y++)
239  {
240  const Costmap::Index index{x, y};
241  const Costmap::Position position = costmap.toPositionGlobal(index);
242 
243  costmap.grid(x, y) = computeCost(position, collisionRobot, robotCollisionModel);
244  }
245  }
246  }
247 
248 
249 } // namespace armarx::navigation::algorithms
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::navigation::algorithms::Costmap::Index
Eigen::Array2i Index
Definition: Costmap.h:46
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
util.h
index
uint8_t index
Definition: EtherCATFrame.h:59
basic_types.h
CostmapBuilder.h
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
ARMARX_CHECK_GREATER
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
Definition: ExpressionException.h:116
trace.h
armarx::navigation::algorithms
This file is part of ArmarX.
Definition: aron_conversions.cpp:13
armarx::navigation::algorithms::CostmapBuilder::createUniformGrid
static Eigen::MatrixXf createUniformGrid(const SceneBounds &sceneBounds, const Costmap::Parameters &parameters)
Definition: CostmapBuilder.cpp:91
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::navigation::algorithms::computeSceneBounds
SceneBounds computeSceneBounds(const VirtualRobot::SceneObjectSetPtr &obstacles, const std::vector< VirtualRobot::RobotPtr > &articulatedObjects, const SceneBounds &init, const float margin)
Definition: util.cpp:56
armarx::navigation::algorithms::Costmap::getGrid
const Grid & getGrid() const
Definition: Costmap.cpp:236
armarx::navigation::util::articulatedObjects
objpose::ObjectPoseSeq articulatedObjects(objpose::ObjectPoseSeq objects)
Definition: util.cpp:95
armarx::navigation::algorithms::Costmap::Position
Eigen::Vector2f Position
Definition: Costmap.h:47
max
T max(T t1, T t2)
Definition: gdiam.h:48
armarx::navigation::algorithms::SceneBounds
Definition: types.h:29
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
ExpressionException.h
armarx::navigation::algorithms::SceneBounds::min
Eigen::Vector2f min
Definition: types.h:31
armarx::navigation::algorithms::CostmapBuilder::create
Costmap create(const SceneBounds &init=SceneBounds())
Definition: CostmapBuilder.cpp:61
armarx::navigation::algorithms::CostmapBuilder::CostmapBuilder
CostmapBuilder(const VirtualRobot::RobotPtr &robot, const VirtualRobot::SceneObjectSetPtr &obstacles, const std::vector< VirtualRobot::RobotPtr > &articulatedObjects, const Costmap::Parameters &parameters, const std::string &robotCollisonModelName)
Definition: CostmapBuilder.cpp:44
armarx::navigation::algorithms::Costmap::Parameters::cellSize
float cellSize
How big each cell is in the uniform grid.
Definition: Costmap.h:27
armarx::navigation::conv::to3D
std::vector< Eigen::Vector3f > to3D(const std::vector< Eigen::Vector2f > &v)
Definition: eigen.cpp:11
armarx::navigation::algorithms::Costmap::Parameters
Definition: Costmap.h:21
eigen.h
Logging.h
min
T min(T t1, T t2)
Definition: gdiam.h:42
armarx::navigation::algorithms::Costmap::Parameters::sceneBoundsMargin
float sceneBoundsMargin
Definition: Costmap.h:29
types.h
armarx::navigation::algorithms::SceneBounds::max
Eigen::Vector2f max
Definition: types.h:32
armarx::navigation::algorithms::Costmap
Definition: Costmap.h:13
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18