29 operator+(
const armarx::Vector3IBase& lhs,
const armarx::Vector3IBase& rhs)
31 return armarx::Vector3IBase{lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z};
35 AStarPathPlannerBase(250.f,
64 s <<
"Invalid translation step size: " << step <<
" < 0.0";
66 throw armarx::InvalidArgumentException{
s.str()};
78 stepSizeDeg =
static_cast<int>(step /
M_PI * 180);
83 const ::Ice::Current&)
85 if (range.max < range.min)
88 s <<
"Invalid bounding range for x dimension: min = " << range.min
89 <<
", max = " << range.max;
91 throw armarx::InvalidArgumentException{
s.str()};
94 xBoundingRange = range;
99 const ::Ice::Current&)
101 if (range.max < range.min)
104 s <<
"Invalid bounding range for y dimension: min = " << range.min
105 <<
", max = " << range.max;
107 throw armarx::InvalidArgumentException{
s.str()};
110 yBoundingRange = range;
115 const ::Ice::Current&)
117 neighbourDeltas = neighbours;
123 rotationFactorForHeuristic = factor;
129 distanceFactorForHeuristic = factor;
136 return distanceFactorForHeuristic * std::hypot(delta(0), delta(1)) +
137 rotationFactorForHeuristic *
std::abs(delta(2));
142 const armarx::Vector3IBase& to)
const
144 return distanceFactorForHeuristic * std::hypot(to.x - from.x, to.y - from.y) +
145 rotationFactorForHeuristic *
std::abs(to.z - from.z);
149 ::armarx::Vector3BaseList
151 const ::armarx::Vector3BasePtr& to,
152 const ::Ice::Current&)
const
162 if (!(isPositionValid(
Vector3{from->x, from->y, from->z}) &&
163 isPositionValid(
Vector3{to->x, to->y, to->z})))
165 return Vector3BaseList{};
172 ARMARX_VERBOSE <<
"Planning path from (" << from->x <<
", " << from->y <<
", " << from->z
173 <<
") to (" << to->x <<
", " << to->y <<
", " << to->z <<
")";
175 auto toGlobal = [&](
const armarx::Vector3IBase& node)
178 from->y + node.y * tStepSize,
179 from->z +
static_cast<float>(node.z *
M_PI / 180)};
182 auto getNeighbours = [&](
const armarx::Vector3IBase& node)
184 armarx::Vector3IBaseList neighbours;
186 for (
const auto& delta : neighbourDeltas)
188 armarx::Vector3IBase neighbour{
191 (((node.z + delta.z * stepSizeDeg) % 360) + 360) %
196 if (globalNeighbour.x <= xBoundingRange.max &&
197 globalNeighbour.x >= xBoundingRange.min &&
198 globalNeighbour.y <= yBoundingRange.max &&
199 globalNeighbour.y >= yBoundingRange.min && isPositionValid(globalNeighbour))
201 neighbours.push_back(neighbour);
218 const armarx::Vector3IBase start{0, 0, 0};
220 armarx::Vector3 fromToDelta{to->x - from->x, to->y - from->y, to->z - from->z};
222 armarx::Vector3IBase goal{
static_cast<int>(std::lround(fromToDelta.x / tStepSize)),
223 static_cast<int>(std::lround(fromToDelta.y / tStepSize)),
224 ((
static_cast<int>(fromToDelta.z /
M_PI * 180) % 360) + 360) %
228 int goalZMod = goal.z % stepSizeDeg;
229 goal.z = goal.z - goalZMod;
230 goal.z += ((goalZMod >= stepSizeDeg / 2) ? stepSizeDeg : 0);
233 assert(globalGoalPtr);
235 ::armarx::Vector3BaseList path{};
236 std::vector<armarx::Vector3IBase> openSet{};
237 std::vector<armarx::Vector3IBase> closedSet{};
239 openSet.push_back(start);
241 std::map<armarx::Vector3IBase, float> fScore;
242 std::map<armarx::Vector3IBase, float> gScore;
244 fScore[start] = gScore.at(start) + heuristic(
toGlobal(start), *globalGoalPtr);
246 std::map<armarx::Vector3IBase, armarx::Vector3IBase> cameFrom;
247 cameFrom[goal] = start;
254 while (!openSet.empty())
258 std::min_element(openSet.begin(),
260 [&](
const armarx::Vector3IBase&
a,
const armarx::Vector3IBase& b)
261 { return fScore.at(a) < fScore.at(b); });
262 assert(currentIT != openSet.end());
263 const armarx::Vector3IBase current = *currentIT;
266 if ((current.x == goal.x) && (current.y == goal.y) && (current.z == goal.z))
270 armarx::Vector3IBase cameFromNode = goal;
272 while (cameFromNode != start)
274 armarx::Vector3BasePtr globalCameFromNodePtr =
276 path.insert(path.begin(), globalCameFromNodePtr);
277 cameFromNode = cameFrom.at(cameFromNode);
280 path.insert(path.begin(), from);
284 openSet.erase(currentIT);
285 closedSet.push_back(current);
290 for (
const armarx::Vector3IBase& neighbour : getNeighbours(current))
292 if (std::find(closedSet.begin(), closedSet.end(), neighbour) != closedSet.end())
301 float tentativeGScore = gScore.at(current) + heuristic(current, neighbour);
302 bool notInOS = std::find(openSet.begin(), openSet.end(), neighbour) == openSet.end();
304 if (notInOS || tentativeGScore < gScore.at(neighbour))
306 cameFrom[neighbour] = current;
307 gScore[neighbour] = tentativeGScore;
309 fScore[neighbour] = tentativeGScore + heuristic(neighbour, goal);
315 openSet.push_back(neighbour);