27 #include <VirtualRobot/MathTools.h>
33 #include "../PlatformContext.h"
40 using namespace PlatformGroup;
55 Eigen::Vector2f& closest,
59 Eigen::Vector2f robotLocation(currentX, currentY);
62 for (
auto& basenode : nodes)
66 auto size = node->getOutdegree();
67 for (
int i = 0; i < size; ++i)
70 memoryx::GraphNodePtr::dynamicCast(node->getAdjacentNode(i)->getEntity());
72 Eigen::Vector2f node1 =
73 FramedPosePtr::dynamicCast(node->getPose())->toEigen().block<2, 1>(0, 3);
74 Eigen::Vector2f node2 =
75 FramedPosePtr::dynamicCast(nextNode->getPose())->toEigen().block<2, 1>(0, 3);
77 if ((node1 - node2).norm() > 1e-9)
79 Eigen::Vector2f result =
80 VirtualRobot::MathTools::nearestPointOnSegment<Eigen::Vector2f>(
81 node1, node2, robotLocation);
83 if ((closest.x() == 0 && closest.y() == 0) ||
84 (result - robotLocation).norm() < (closest - robotLocation).norm())
94 return (closest.x() != 0 || closest.y() != 0);
107 std::vector<EdgeProjection>
110 std::vector<EdgeProjection> projections;
112 for (
auto& basenode : nodes)
116 auto size = node->getOutdegree();
117 for (
int i = 0; i < size; ++i)
120 memoryx::GraphNodePtr::dynamicCast(node->getAdjacentNode(i)->getEntity());
122 Eigen::Vector2f node1 =
123 FramedPosePtr::dynamicCast(node->getPose())->toEigen().block<2, 1>(0, 3);
124 Eigen::Vector2f node2 =
125 FramedPosePtr::dynamicCast(nextNode->getPose())->toEigen().block<2, 1>(0, 3);
127 if ((node1 - node2).norm() > 1e-9)
129 Eigen::Vector2f result =
130 VirtualRobot::MathTools::nearestPointOnSegment<Eigen::Vector2f>(
131 node1, node2, robotPos);
151 std::vector<armarx::Vector3Ptr> targetPositions;
154 const std::string sceneName = in.getSceneName();
155 if (!graphSegment->hasScene(sceneName))
157 ARMARX_WARNING <<
"Target scene '" << sceneName <<
"' does not exist in menory";
158 out.settargetPositions(targetPositions);
164 const std::string landmark = in.gettargetLandmark();
165 if (!graphSegment->hasNodeWithName(sceneName, landmark))
167 ARMARX_WARNING <<
"Target landmark '" << landmark <<
"' doesn't exist in graph (scene) '"
169 auto nodes = graphSegment->getNodesByScene(sceneName);
170 for (
auto& node : nodes)
174 out.settargetPositions(targetPositions);
175 sendEvent<EvNoPathFound>();
179 memoryx::GraphNodeBasePtr goalNode;
181 memoryx::GraphNodeBasePtr landmarkNode =
182 graphSegment->getNodeFromSceneByName(sceneName, landmark);
184 <<
"Could not find node with name '" << landmark <<
"' in scene '" << sceneName <<
"'";
188 <<
"' in scene '" << sceneName <<
"'";
190 ARMARX_INFO <<
"Resolved target landmark to '" << goalNode->getName() <<
"'";
199 const float platformPositionX = poseRef->getDataField(
"positionX")->getFloat();
200 const float platformPositionY = poseRef->getDataField(
"positionY")->getFloat();
201 const float platformYaw = poseRef->getDataField(
"rotation")->getFloat();
203 Eigen::Vector3f currentPos(platformPositionX, platformPositionY, 0);
204 const Eigen::Vector2f currentPos2d = currentPos.head<2>();
210 .
orientation(VirtualRobot::MathTools::rpy2eigen3f(0, 0, platformYaw)));
213 std::vector<EdgeProjection> projections =
215 if (projections.empty())
217 ARMARX_ERROR <<
"Could not find nearest point on graph";
222 std::sort(projections.begin(),
224 [¤tPos2d](
const auto& p1,
const auto& p2)
226 const float c1 = (p1.position - currentPos2d).norm();
227 const float c2 = (p2.position - currentPos2d).norm();
233 std::optional<EdgeProjection> bestProjection;
234 ::memoryx::GraphNodeBaseList bestPath;
239 const Eigen::Vector3f nodePosition =
fromIce(projection.targetNode->getPose()->position);
240 const float distToNode = (nodePosition - currentPos).
norm();
241 ARMARX_INFO <<
"Current node: '" << projection.targetNode->getName() <<
"' | "
245 ::memoryx::GraphNodeBaseList path =
246 graphSegment->aStar(projection.targetNode->getId(), goalNode->getId());
257 if (bestProjection.has_value() and
258 (bestProjection->position - projection.position).norm() > 1e-4)
263 if (pathCost < bestPathCosts)
265 bestProjection = projection;
267 bestPathCosts = pathCost;
271 if (not bestProjection.has_value())
274 out.settargetPositions(targetPositions);
279 const Eigen::Vector2f nearestPoint = bestProjection->position;
280 ARMARX_INFO <<
"Nearest Point on graph: " << nearestPoint.transpose();
282 Eigen::Vector3f closestPointPos;
283 closestPointPos << nearestPoint, 0;
286 .position(closestPointPos)
290 .fromTo(currentPos, closestPointPos)
297 bool fixedOrentation =
true;
300 bool useWaypointOrientations = in.getUseWaypointOrientations();
301 if (!useWaypointOrientations && length > in.getdriveMode_lookAhead_thresholdMM())
304 <<
" mm) -> rotating platform towards moving direction";
305 fixedOrentation =
false;
309 PosePtr pose = PosePtr::dynamicCast(bestPath.back()->getPose());
310 VirtualRobot::MathTools::eigen4f2rpy(pose->toEigen(), rpy);
311 const float goalYaw = rpy[2];
316 for (
auto& node : bestPath)
320 v->x = currentPose->position->x;
321 v->y = currentPose->position->y;
323 if (useWaypointOrientations)
325 VirtualRobot::MathTools::eigen4f2rpy(currentPose->toEigen(), rpy);
329 else if (fixedOrentation)
335 if (count <= 0 || count >=
int(bestPath.size() - 1))
338 VirtualRobot::MathTools::eigen4f2rpy(currentPose->toEigen(), rpy);
339 ARMARX_DEBUG <<
"start or last pose of path, using orientation of waypoint: "
346 double x = currentPose->position->x - lastPose->position->x;
347 double y = currentPose->position->y - lastPose->position->y;
352 ARMARX_DEBUG <<
"points close together, using last orientation: " << lastAlpha;
358 Eigen::Vector2d
a(
x, y);
360 Eigen::Vector2d b(0, 1);
361 v->z = -(std::atan2(b.y(), b.x()) - std::atan2(
a.y(),
a.x()));
370 ARMARX_DEBUG <<
"waypoint angle between " <<
a.transpose() <<
" and "
371 << b.transpose() <<
": " <<
v->z;
375 lastPose = currentPose;
379 targetPositions.push_back(
v);
380 ARMARX_INFO <<
"waypoint #" << targetPositions.size() <<
": " << node->getName()
381 <<
" Coordinates:\n " <<
v->output();
387 Vector3Ptr::dynamicCast(targetPositions[0])->toEigen().z()));
388 targetPositions.insert(targetPositions.begin(),
v);
390 out.settargetPositions(targetPositions);
398 context->
debugDrawer->removeSphereDebugLayerVisu(
"closestPoint");
405 ::armarx::FramedPoseBasePtr lastPose;
407 for (
auto& node : path)
411 lastPose = node->getPose();
415 ::armarx::FramedPoseBasePtr currentPose = node->getPose();
416 float x = currentPose->position->x - lastPose->position->x;
417 float y = currentPose->position->y - lastPose->position->y;
419 lastPose = currentPose;