GCC Code Coverage Report


Directory: ./
File: src/problem-target/astar.hh
Date: 2025-03-07 11:10:46
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