Navigator.cpp
Go to the documentation of this file.
1#include "Navigator.h"
2
3#include <chrono>
4#include <cstdint>
5#include <functional>
6#include <future>
7#include <mutex>
8#include <string>
9#include <vector>
10
15
21
23{
24
25 Navigator::Navigator(const InjectedServices& services) : srv{services}
26 {
28 // these checks cannot be used when component is started in property-readout mode
29 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
30 ARMARX_CHECK_NOT_NULL(srv.subscriber) << "Subscriber service must not be null!";
31
32 auto stopped_callback = [this](const auto& e) { stopped(StopEvent(e)); };
33
34 srv.subscriber->onGoalReached(stopped_callback);
35 srv.subscriber->onSafetyStopTriggered(stopped_callback);
36 srv.subscriber->onUserAbortTriggered(stopped_callback);
37 srv.subscriber->onInternalError(stopped_callback);
38 srv.subscriber->onGlobalPlanningFailed(stopped_callback);
39 }
40
41 void
43 {
45 moveTo(std::vector<core::Pose>{pose}, frame);
46 }
47
48 void
49 Navigator::moveTo(const std::vector<core::Pose>& waypoints, core::NavigationFrame frame)
50 {
52 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
53 {
54 // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
55 // after the event is reset
56 std::scoped_lock const l{stoppedInfo.m};
57 stoppedInfo.event.reset();
58 }
59 srv.navigator->moveTo(waypoints, frame);
60 }
61
62 void
64 {
66 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
67
68 const std::vector<WaypointTarget>& path = builder.path();
69 validate(path);
70
71 {
72 // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
73 // after the event is reset
74 std::scoped_lock const l{stoppedInfo.m};
75 stoppedInfo.event.reset();
76 }
77 srv.navigator->moveTo(path, frame);
78 }
79
80 void
81 Navigator::moveToAlternatives(const std::vector<core::TargetAlternative>& targets,
83 {
85 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
86
87 {
88 // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
89 // after the event is reset
90 std::scoped_lock const l{stoppedInfo.m};
91 stoppedInfo.event.reset();
92 }
93 srv.navigator->moveToAlternatives(targets, frame);
94 }
95
96 void
97 Navigator::update(const std::vector<core::Pose>& waypoints, core::NavigationFrame frame)
98 {
100 ;
101 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
102 srv.navigator->update(waypoints, frame);
103 }
104
105 void
107 {
109 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
110
111 {
112 // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
113 // after the event is reset
114 std::scoped_lock const l{stoppedInfo.m};
115 stoppedInfo.event.reset();
116 }
117 srv.navigator->moveTowards(direction, frame);
118 }
119
120 void
122 const std::optional<std::string>& providerName)
123 {
125 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
126
127 {
128 // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
129 // after the event is reset
130 std::scoped_lock const l{stoppedInfo.m};
131 stoppedInfo.event.reset();
132 }
133 srv.navigator->moveToLocation(location, providerName);
134 }
135
136 void
137 Navigator::setVelocityFactor(float velocityFactor)
138 {
140 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
141 srv.navigator->setVelocityFactor(velocityFactor);
142 }
143
144 void
146 {
148 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
149 srv.navigator->pause();
150 }
151
152 void
154 {
156 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
157 srv.navigator->resume();
158 }
159
160 void
162 {
164 ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
165 srv.navigator->stop();
166 }
167
168 void
169 Navigator::onGoalReached(const std::function<void(void)>& callback)
170 {
172 onGoalReached([&callback](const core::GoalReachedEvent&) { callback(); });
173 }
174
175 void
176 Navigator::onGoalReached(const std::function<void(const core::GoalReachedEvent&)>& callback)
177 {
178 }
179
180 void
181 Navigator::onWaypointReached(const std::function<void(int)>& callback)
182 {
183 }
184
186 Navigator::waitForStop(const std::int64_t timeoutMs)
187 {
189
190 std::future<void> future = std::async(
191 std::launch::async,
192 [&]()
193 {
194 std::unique_lock l{stoppedInfo.m};
195 stoppedInfo.cv.wait(l, [&i = stoppedInfo] { return i.event.has_value(); });
196 });
197
198
199 if (timeoutMs > 0)
200 {
201 ARMARX_VERBOSE << "future.wait()";
202 auto status = future.wait_for(std::chrono::milliseconds(timeoutMs));
203 ARMARX_VERBOSE << "done";
204
205 switch (status)
206 {
207 case std::future_status::ready:
208 ARMARX_INFO << "waitForStop: terminated on goal reached";
209 break;
210 case std::future_status::timeout:
211 ARMARX_INFO << "waitForStop: terminated due to timeout";
212 ARMARX_INFO << "Stopping robot due to timeout";
213 stop();
214
215 throw LocalException("Navigator::waitForStop: timeout");
216 break;
217 case std::future_status::deferred:
218 ARMARX_INFO << "waitForStop: deferred";
219 break;
220 }
221 }
222 else
223 {
224 ARMARX_VERBOSE << "future.wait()";
225 future.wait();
226 ARMARX_VERBOSE << "done";
227 }
228
229 // only due to timeout, stoppedInfo.event should be nullopt
230 ARMARX_CHECK(stoppedInfo.event.has_value());
231
232 StopEvent e = stoppedInfo.event.value();
233 stoppedInfo.event.reset();
234
235 return e;
236 }
237
238 void
239 Navigator::stopped(const StopEvent& e)
240 {
242 {
243 std::scoped_lock l{stoppedInfo.m};
244 stoppedInfo.event = e;
245 }
246 stoppedInfo.cv.notify_all();
247 }
248
249} // namespace armarx::navigation::client
void setVelocityFactor(float velocityFactor)
void update(const std::vector< core::Pose > &waypoints, core::NavigationFrame frame)
Definition Navigator.cpp:97
void moveToLocation(const std::string &location, const std::optional< std::string > &providerName)
Navigator(const InjectedServices &services)
Definition Navigator.cpp:25
void moveTo(const core::Pose &pose, core::NavigationFrame frame)
Definition Navigator.cpp:42
void moveToAlternatives(const std::vector< core::TargetAlternative > &targets, core::NavigationFrame frame)
Definition Navigator.cpp:81
StopEvent waitForStop(std::int64_t timeoutMs=-1)
void moveTowards(const core::Direction &direction, core::NavigationFrame frame)
void onGoalReached(const std::function< void(void)> &callback)
void onWaypointReached(const std::function< void(int)> &callback)
const WaypointTargets & path() const
Brief description of class targets.
Definition targets.h:39
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file is part of ArmarX.
void validate(const std::vector< WaypointTarget > &path)
Eigen::Vector3f Direction
Definition basic_types.h:39
Eigen::Isometry3f Pose
Definition basic_types.h:31
This file is part of ArmarX.
Definition constants.cpp:4
Event describing that the targeted goal was successfully reached.
Definition events.h:53
#define ARMARX_TRACE
Definition trace.h:77