Navigator.cpp
Go to the documentation of this file.
1 #include "Navigator.h"
2 
3 #include <algorithm>
4 #include <chrono>
5 #include <future>
6 
11 
14 
16 {
17 
18  Navigator::Navigator(const InjectedServices& services) : srv{services}
19  {
21  // these checks cannot be used when component is started in property-readout mode
22  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
23  ARMARX_CHECK_NOT_NULL(srv.subscriber) << "Subscriber service must not be null!";
24 
25  auto stopped_callback = [this](const auto& e) { stopped(StopEvent(e)); };
26 
27  srv.subscriber->onGoalReached(stopped_callback);
28  srv.subscriber->onSafetyStopTriggered(stopped_callback);
29  srv.subscriber->onUserAbortTriggered(stopped_callback);
30  srv.subscriber->onInternalError(stopped_callback);
31  srv.subscriber->onGlobalPlanningFailed(stopped_callback);
32  }
33 
34 
35  void
37  {
39  moveTo(std::vector<core::Pose>{pose}, frame);
40  }
41 
42 
43  void
44  Navigator::moveTo(const std::vector<core::Pose>& waypoints, core::NavigationFrame frame)
45  {
47  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
48  {
49  // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
50  // after the event is reset
51  std::scoped_lock const l{stoppedInfo.m};
52  stoppedInfo.event.reset();
53  }
54  srv.navigator->moveTo(waypoints, frame);
55  }
56 
57 
58  void
60  {
62  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
63 
64  const std::vector<WaypointTarget>& path = builder.path();
65  validate(path);
66 
67  {
68  // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
69  // after the event is reset
70  std::scoped_lock const l{stoppedInfo.m};
71  stoppedInfo.event.reset();
72  }
73  srv.navigator->moveTo(path, frame);
74  }
75 
76  void Navigator::update(const std::vector<core::Pose>& waypoints, core::NavigationFrame frame)
77  {
78  ARMARX_TRACE;;
79  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
80  srv.navigator->update(waypoints, frame);
81  }
82 
83 
84  void
86  {
88  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
89 
90  {
91  // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
92  // after the event is reset
93  std::scoped_lock const l{stoppedInfo.m};
94  stoppedInfo.event.reset();
95  }
96  srv.navigator->moveTowards(direction, frame);
97  }
98 
99  void Navigator::moveToLocation(const std::string& location)
100  {
101  ARMARX_TRACE;
102  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
103 
104  {
105  // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
106  // after the event is reset
107  std::scoped_lock const l{stoppedInfo.m};
108  stoppedInfo.event.reset();
109  }
110  srv.navigator->moveToLocation(location);
111  }
112 
113 
114  void
116  {
117  ARMARX_TRACE;
118  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
119  srv.navigator->pause();
120  }
121 
122 
123  void
125  {
126  ARMARX_TRACE;
127  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
128  srv.navigator->resume();
129  }
130 
131 
132  void
134  {
135  ARMARX_TRACE;
136  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
137  srv.navigator->stop();
138  }
139 
140 
141  void
142  Navigator::onGoalReached(const std::function<void(void)>& callback)
143  {
144  ARMARX_TRACE;
145  onGoalReached([&callback](const core::GoalReachedEvent&) { callback(); });
146  }
147 
148 
149  void
150  Navigator::onGoalReached(const std::function<void(const core::GoalReachedEvent&)>& callback)
151  {
152  }
153 
154 
155  void
156  Navigator::onWaypointReached(const std::function<void(int)>& callback)
157  {
158  }
159 
160 
161  StopEvent
162  Navigator::waitForStop(const std::int64_t timeoutMs)
163  {
164  ARMARX_TRACE;
165 
166  std::future<void> future = std::async(
167  std::launch::async,
168  [&]()
169  {
170  std::unique_lock l{stoppedInfo.m};
171  stoppedInfo.cv.wait(l, [&i = stoppedInfo] { return i.event.has_value(); });
172  });
173 
174 
175  if (timeoutMs > 0)
176  {
177  ARMARX_VERBOSE << "future.wait()";
178  auto status = future.wait_for(std::chrono::milliseconds(timeoutMs));
179  ARMARX_VERBOSE << "done";
180 
181  switch (status)
182  {
183  case std::future_status::ready:
184  ARMARX_INFO << "waitForStop: terminated on goal reached";
185  break;
186  case std::future_status::timeout:
187  ARMARX_INFO << "waitForStop: terminated due to timeout";
188  ARMARX_INFO << "Stopping robot due to timeout";
189  stop();
190 
191  throw LocalException("Navigator::waitForStop: timeout");
192  break;
193  case std::future_status::deferred:
194  ARMARX_INFO << "waitForStop: deferred";
195  break;
196  }
197  }
198  else
199  {
200  ARMARX_VERBOSE << "future.wait()";
201  future.wait();
202  ARMARX_VERBOSE << "done";
203  }
204 
205  // only due to timeout, stoppedInfo.event should be nullopt
206  ARMARX_CHECK(stoppedInfo.event.has_value());
207 
208  StopEvent e = stoppedInfo.event.value();
209  stoppedInfo.event.reset();
210 
211  return e;
212  }
213 
214 
215  void
216  Navigator::stopped(const StopEvent& e)
217  {
218  ARMARX_TRACE;
219  {
220  std::scoped_lock l{stoppedInfo.m};
221  stoppedInfo.event = e;
222  }
223  stoppedInfo.cv.notify_all();
224  }
225 
226 } // namespace armarx::navigation::client
ice_conversions.h
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::navigation::client::Navigator::onGoalReached
void onGoalReached(const std::function< void(void)> &callback)
Definition: Navigator.cpp:142
Navigator.h
armarx::navigation::client::Navigator::waitForStop
StopEvent waitForStop(std::int64_t timeoutMs=-1)
Definition: Navigator.cpp:162
LocalException.h
armarx::navigation::core::NavigationFrame
NavigationFrame
Definition: types.h:43
armarx::navigation::client::Navigator::InjectedServices
Definition: Navigator.h:119
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
armarx::navigation::client::PathBuilder
Definition: PathBuilder.h:41
ARMARX_CHECK_NOT_NULL
#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...
Definition: ExpressionException.h:206
trace.h
armarx::navigation::client
This file is part of ArmarX.
Definition: ComponentPlugin.cpp:20
armarx::navigation::client::Navigator::InjectedServices::navigator
core::NavigatorInterface * navigator
Definition: Navigator.h:121
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::navigation::core::NavigatorInterface::moveToLocation
virtual void moveToLocation(const std::string &location)=0
armarx::navigation::client::Navigator::update
void update(const std::vector< core::Pose > &waypoints, core::NavigationFrame frame)
Definition: Navigator.cpp:76
armarx::navigation::client::Navigator::onWaypointReached
void onWaypointReached(const std::function< void(int)> &callback)
Definition: Navigator.cpp:156
armarx::navigation::client::StopEvent
Definition: Navigator.h:42
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
armarx::status
status
Definition: FiniteStateMachine.h:259
armarx::navigation::client::Navigator::Navigator
Navigator(const InjectedServices &services)
Definition: Navigator.cpp:18
PathBuilder.h
armarx::navigation::client::Navigator::resume
void resume()
Definition: Navigator.cpp:124
armarx::navigation::client::Navigator::moveToLocation
void moveToLocation(const std::string &location)
Definition: Navigator.cpp:99
armarx::navigation::client::Navigator::moveTowards
void moveTowards(const core::Direction &direction, core::NavigationFrame frame)
Definition: Navigator.cpp:85
armarx::navigation::core::NavigatorInterface::moveTo
virtual void moveTo(const std::vector< core::Pose > &waypoints, core::NavigationFrame navigationFrame)=0
armarx::navigation::core::NavigatorInterface::moveTowards
virtual void moveTowards(const core::Direction &direction, core::NavigationFrame navigationFrame)=0
armarx::navigation::core::GoalReachedEvent
Event describing that the targeted goal was successfully reached.
Definition: events.h:49
armarx::navigation::client::Navigator::pause
void pause()
Definition: Navigator.cpp:115
ExpressionException.h
armarx::navigation::client::validate
void validate(const std::vector< WaypointTarget > &path)
Definition: ice_conversions.h:70
armarx::navigation::core::NavigatorInterface::update
virtual void update(const std::vector< core::Pose > &waypoints, core::NavigationFrame navigationFrame)=0
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::navigation::core::Direction
Eigen::Vector3f Direction
Definition: basic_types.h:39
armarx::navigation::client::Navigator::stop
void stop()
Definition: Navigator.cpp:133
armarx::navigation::client::PathBuilder::path
const WaypointTargets & path() const
Definition: PathBuilder.cpp:32
Logging.h
armarx::navigation::core::NavigatorInterface::pause
virtual void pause()=0
armarx::navigation::core::NavigatorInterface::stop
virtual void stop()=0
armarx::navigation::core::NavigatorInterface::resume
virtual void resume()=0
armarx::navigation::client::Navigator::moveTo
void moveTo(const core::Pose &pose, core::NavigationFrame frame)
Definition: Navigator.cpp:36