45 costmapParameters_(costmapParameters), handoverParameters_(handoverParameters)
50 handoverParameters_.handoverDistanceMin);
53 handoverParameters_.handoverAngleMax);
56 handoverParameters_.handoverAnglePreference);
58 handoverParameters_.handoverAngleMax);
64 const std::optional<core::Pose2D> global_T_human_opt =
67 if (not global_T_human_opt.has_value())
74 const auto sceneBounds = [
this, global_T_human = global_T_human_opt.value()]
77 const Eigen::Vector2f human_T_left{-handoverParameters_.humanSceneBoundOffsetSideLeft,
79 const Eigen::Vector2f human_T_right{handoverParameters_.humanSceneBoundOffsetSideRight,
81 const Eigen::Vector2f human_T_front{0, handoverParameters_.humanSceneBoundOffsetFront};
83 const Eigen::Vector2f human_T_back{0, -handoverParameters_.humanSceneBoundOffsetBehind};
88 global_T_human * human_T_right,
89 global_T_human * human_T_front,
90 global_T_human * human_T_back},
100 const auto projectToInterval =
101 [](
const float value,
const float min,
const float max,
const float preference) ->
float
112 if (value == preference)
116 if (value < preference)
118 return -((preference - value) / (preference -
min));
121 return (value - preference) / (
max - preference);
124 const auto costFn = [
this, &projectToInterval](
float distanceToObstacle,
125 float distanceToHuman,
126 float angleToHuman) -> std::optional<float>
129 if (distanceToHuman < handoverParameters_.handoverDistanceMin ||
130 distanceToHuman > handoverParameters_.handoverDistanceMax)
135 if (angleToHuman < handoverParameters_.handoverAngleMin ||
136 angleToHuman > handoverParameters_.handoverAngleMax)
143 const float xDistance =
144 projectToInterval(distanceToHuman,
145 handoverParameters_.handoverDistanceMin,
146 handoverParameters_.handoverDistanceMax,
147 handoverParameters_.handoverDistancePreference);
148 const float xAngle = projectToInterval(angleToHuman,
149 handoverParameters_.handoverAngleMin,
150 handoverParameters_.handoverAngleMax,
151 handoverParameters_.handoverAnglePreference);
155 const double fDistance = std::abs(std::tan(xDistance * M_PI_2));
156 const double fAngle = std::abs(std::tan(xAngle * M_PI_2));
162 const double f = (fDistance + 1) * (fAngle + 1);
166 const double obstaclePenalty =
167 (distanceToObstacle < handoverParameters_.obstacleProximityThreshold)
168 ? handoverParameters_.obstacleProximityPenalty
171 return static_cast<float>(f + obstaclePenalty);
186 [&
costmap, &sceneInfo, global_T_human = global_T_human_opt.value(), &costFn](
190 const auto global_P_cell = costmap.toPositionGlobal(idx);
194 const auto vertex = sceneInfo.distanceMap.toVertexOrInvalid(global_P_cell);
198 costmap.getMutableGrid()(idx.x(), idx.y()) = 0.0f;
199 costmap.getMutableMask()->operator()(idx.x(), idx.y()) = false;
202 if (!vertex.has_value())
222 const float distanceToObstacle =
223 sceneInfo.distanceMap.getGrid()(vertex->index.x(), vertex->index.y());
224 const Eigen::Vector2f human_P_cell = global_T_human.inverse() * global_P_cell;
226 const float distanceToHuman = human_P_cell.norm();
228 const float angleToHuman = std::atan2(human_P_cell.y(), human_P_cell.x());
231 const auto costOpt = costFn(distanceToObstacle, distanceToHuman, angleToHuman);
233 if (not costOpt.has_value())
239 costmap.getMutableGrid()(idx.x(), idx.y()) = costOpt.value();
240 costmap.getMutableMask()->operator()(idx.x(), idx.y()) =
true;