GCC Code Coverage Report


Directory: ./
File: src/problem-target/astar.hh
Date: 2025-05-07 11:07:45
Exec Total Coverage
Lines: 0 69 0.0%
Branches: 0 92 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2014 CNRS
3 // Authors: Florent Lamiraux
4 //
5
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 // 1. Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //
13 // 2. Redistributions in binary form must reproduce the above copyright
14 // notice, this list of conditions and the following disclaimer in the
15 // documentation and/or other materials provided with the distribution.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28 // DAMAGE.
29
30 #ifndef HPP_MANIPULATION_PROBLEM_TARGET_ASTAR_HH
31 #define HPP_MANIPULATION_PROBLEM_TARGET_ASTAR_HH
32
33 #include <hpp/core/distance.hh>
34 #include <hpp/core/edge.hh>
35 #include <hpp/core/node.hh>
36 #include <hpp/core/path-vector.hh>
37 #include <hpp/manipulation/config.hh>
38 #include <hpp/manipulation/fwd.hh>
39 #include <hpp/manipulation/roadmap-node.hh>
40 #include <hpp/manipulation/roadmap.hh>
41 #include <hpp/util/exception-factory.hh>
42 #include <limits>
43
44 namespace hpp {
45 namespace manipulation {
46 namespace problemTarget {
47 class HPP_MANIPULATION_LOCAL Astar {
48 typedef core::PathVectorPtr_t PathVectorPtr_t;
49 typedef core::EdgePtr_t EdgePtr_t;
50 typedef std::vector<RoadmapNodePtr_t> Nodes_t;
51 typedef std::list<EdgePtr_t> Edges_t;
52 typedef std::map<core::NodePtr_t, EdgePtr_t> Parent_t;
53 Nodes_t closed_;
54 Nodes_t open_;
55 std::map<RoadmapNodePtr_t, value_type> costFromStart_;
56 std::map<RoadmapNodePtr_t, value_type> estimatedCostToGoal_;
57 Parent_t parent_;
58 core::RoadmapPtr_t roadmap_;
59 core::DistancePtr_t distance_;
60 graph::StatePtr_t state_;
61
62 public:
63 ✗ Astar(const core::RoadmapPtr_t& roadmap, const core::DistancePtr_t distance,
64 graph::StatePtr_t state)
65 ✗ : roadmap_(roadmap), distance_(distance), state_(state) {}
66
67 ✗ PathVectorPtr_t solution() {
68 ✗ core::NodePtr_t node = findPath();
69 ✗ Edges_t edges;
70
71 ✗ while (node) {
72 ✗ Parent_t::const_iterator itEdge = parent_.find(node);
73 ✗ if (itEdge != parent_.end()) {
74 ✗ EdgePtr_t edge = itEdge->second;
75 ✗ edges.push_front(edge);
76 ✗ node = edge->from();
77 } else
78 ✗ node = RoadmapNodePtr_t(0x0);
79 }
80 ✗ PathVectorPtr_t pathVector;
81 ✗ for (Edges_t::const_iterator itEdge = edges.begin(); itEdge != edges.end();
82 ✗ ++itEdge) {
83 ✗ const core::PathPtr_t& path((*itEdge)->path());
84 ✗ if (!pathVector)
85 ✗ pathVector = core::PathVector::create(path->outputSize(),
86 ✗ path->outputDerivativeSize());
87 ✗ pathVector->appendPath(path);
88 }
89 ✗ return pathVector;
90 }
91
92 private:
93 struct SortFunctor {
94 std::map<RoadmapNodePtr_t, value_type>& cost_;
95 ✗ SortFunctor(std::map<RoadmapNodePtr_t, value_type>& cost) : cost_(cost) {}
96 ✗ bool operator()(const RoadmapNodePtr_t& n1, const RoadmapNodePtr_t& n2) {
97 ✗ return cost_[n1] < cost_[n2];
98 }
99 }; // struc SortFunctor
100
101 ✗ bool isGoal(const RoadmapNodePtr_t node) {
102 ✗ return node->graphState() == state_;
103 }
104
105 ✗ RoadmapNodePtr_t findPath() {
106 ✗ closed_.clear();
107 ✗ open_.clear();
108 ✗ parent_.clear();
109 ✗ estimatedCostToGoal_.clear();
110 ✗ costFromStart_.clear();
111
112 ✗ assert(dynamic_cast<RoadmapNodePtr_t>(roadmap_->initNode()));
113 ✗ open_.push_back(static_cast<RoadmapNodePtr_t>(roadmap_->initNode()));
114 ✗ while (!open_.empty()) {
115 ✗ std::sort(open_.begin(), open_.end(), SortFunctor(estimatedCostToGoal_));
116 ✗ Nodes_t::iterator itv = open_.begin();
117 ✗ RoadmapNodePtr_t current(*itv);
118 ✗ if (isGoal(current)) {
119 ✗ return current;
120 }
121 ✗ open_.erase(itv);
122 ✗ closed_.push_back(current);
123 ✗ for (Edges_t::const_iterator itEdge = current->outEdges().begin();
124 ✗ itEdge != current->outEdges().end(); ++itEdge) {
125 ✗ value_type transitionCost = edgeCost(*itEdge);
126 ✗ assert(dynamic_cast<RoadmapNodePtr_t>((*itEdge)->to()));
127 ✗ RoadmapNodePtr_t child = static_cast<RoadmapNodePtr_t>((*itEdge)->to());
128 ✗ if (std::find(closed_.begin(), closed_.end(), child) == closed_.end()) {
129 // node is not in closed set
130 ✗ value_type tmpCost = costFromStart_[current] + transitionCost;
131 bool childNotInOpenSet =
132 ✗ (std::find(open_.begin(), open_.end(), child) == open_.end());
133 ✗ if ((childNotInOpenSet) || (tmpCost < costFromStart_[child])) {
134 ✗ parent_[child] = *itEdge;
135 ✗ costFromStart_[child] = tmpCost;
136 ✗ estimatedCostToGoal_[child] =
137 ✗ costFromStart_[child] + heuristic(child);
138 ✗ if (childNotInOpenSet) open_.push_back(child);
139 }
140 }
141 }
142 }
143 ✗ throw std::runtime_error("A* failed to find a solution to the goal.");
144 }
145
146 ✗ value_type heuristic(const RoadmapNodePtr_t node) const {
147 ✗ const Configuration_t& config = node->configuration();
148 ✗ value_type res = std::numeric_limits<value_type>::infinity();
149 ✗ for (core::NodeVector_t::const_iterator itGoal =
150 ✗ roadmap_->goalNodes().begin();
151 ✗ itGoal != roadmap_->goalNodes().end(); ++itGoal) {
152 ✗ const Configuration_t& goal = (*itGoal)->configuration();
153 ✗ value_type dist = (*distance_)(config, goal);
154 ✗ if (dist < res) {
155 ✗ res = dist;
156 }
157 }
158 ✗ return res;
159 }
160
161 ✗ value_type edgeCost(const EdgePtr_t& edge) { return edge->path()->length(); }
162 }; // class Astar
163 } // namespace problemTarget
164 } // namespace manipulation
165 } // namespace hpp
166
167 #endif // HPP_MANIPULATION_PROBLEM_TARGET_ASTAR_HH
168