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::update(const std::vector<core::Pose>& waypoints, core::NavigationFrame frame)
82  {
84  ;
85  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
86  srv.navigator->update(waypoints, frame);
87  }
88 
89  void
91  {
93  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
94 
95  {
96  // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
97  // after the event is reset
98  std::scoped_lock const l{stoppedInfo.m};
99  stoppedInfo.event.reset();
100  }
101  srv.navigator->moveTowards(direction, frame);
102  }
103 
104  void
105  Navigator::moveToLocation(const std::string& location)
106  {
107  ARMARX_TRACE;
108  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
109 
110  {
111  // TODO: This still leads to a race condition, if extern a stop event is generated before moveTo but arrives
112  // after the event is reset
113  std::scoped_lock const l{stoppedInfo.m};
114  stoppedInfo.event.reset();
115  }
116  srv.navigator->moveToLocation(location);
117  }
118 
119  void Navigator::setVelocityFactor(float velocityFactor)
120  {
121  ARMARX_TRACE;
122  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
123  srv.navigator->setVelocityFactor(velocityFactor);
124  }
125 
126  void
128  {
129  ARMARX_TRACE;
130  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
131  srv.navigator->pause();
132  }
133 
134  void
136  {
137  ARMARX_TRACE;
138  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
139  srv.navigator->resume();
140  }
141 
142  void
144  {
145  ARMARX_TRACE;
146  ARMARX_CHECK_NOT_NULL(srv.navigator) << "Navigator service must not be null!";
147  srv.navigator->stop();
148  }
149 
150  void
151  Navigator::onGoalReached(const std::function<void(void)>& callback)
152  {
153  ARMARX_TRACE;
154  onGoalReached([&callback](const core::GoalReachedEvent&) { callback(); });
155  }
156 
157  void
158  Navigator::onGoalReached(const std::function<void(const core::GoalReachedEvent&)>& callback)
159  {
160  }
161 
162  void
163  Navigator::onWaypointReached(const std::function<void(int)>& callback)
164  {
165  }
166 
167  StopEvent
168  Navigator::waitForStop(const std::int64_t timeoutMs)
169  {
170  ARMARX_TRACE;
171 
172  std::future<void> future = std::async(
173  std::launch::async,
174  [&]()
175  {
176  std::unique_lock l{stoppedInfo.m};
177  stoppedInfo.cv.wait(l, [&i = stoppedInfo] { return i.event.has_value(); });
178  });
179 
180 
181  if (timeoutMs > 0)
182  {
183  ARMARX_VERBOSE << "future.wait()";
184  auto status = future.wait_for(std::chrono::milliseconds(timeoutMs));
185  ARMARX_VERBOSE << "done";
186 
187  switch (status)
188  {
189  case std::future_status::ready:
190  ARMARX_INFO << "waitForStop: terminated on goal reached";
191  break;
192  case std::future_status::timeout:
193  ARMARX_INFO << "waitForStop: terminated due to timeout";
194  ARMARX_INFO << "Stopping robot due to timeout";
195  stop();
196 
197  throw LocalException("Navigator::waitForStop: timeout");
198  break;
199  case std::future_status::deferred:
200  ARMARX_INFO << "waitForStop: deferred";
201  break;
202  }
203  }
204  else
205  {
206  ARMARX_VERBOSE << "future.wait()";
207  future.wait();
208  ARMARX_VERBOSE << "done";
209  }
210 
211  // only due to timeout, stoppedInfo.event should be nullopt
212  ARMARX_CHECK(stoppedInfo.event.has_value());
213 
214  StopEvent e = stoppedInfo.event.value();
215  stoppedInfo.event.reset();
216 
217  return e;
218  }
219 
220  void
221  Navigator::stopped(const StopEvent& e)
222  {
223  ARMARX_TRACE;
224  {
225  std::scoped_lock l{stoppedInfo.m};
226  stoppedInfo.event = e;
227  }
228  stoppedInfo.cv.notify_all();
229  }
230 
231 } // namespace armarx::navigation::client
ice_conversions.h
armarx::navigation::core::NavigatorInterface::setVelocityFactor
virtual void setVelocityFactor(float velocityFactor)=0
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::navigation::client::Navigator::onGoalReached
void onGoalReached(const std::function< void(void)> &callback)
Definition: Navigator.cpp:151
Navigator.h
armarx::navigation::client::Navigator::waitForStop
StopEvent waitForStop(std::int64_t timeoutMs=-1)
Definition: Navigator.cpp:168
LocalException.h
armarx::navigation::core::NavigationFrame
NavigationFrame
Definition: types.h:42
armarx::navigation::client::Navigator::InjectedServices
Definition: Navigator.h:120
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
basic_types.h
armarx::navigation::client::PathBuilder
Definition: PathBuilder.h:39
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::Navigator::setVelocityFactor
void setVelocityFactor(float velocityFactor)
Definition: Navigator.cpp:119
armarx::navigation::client
This file is part of ArmarX.
Definition: ComponentPlugin.cpp:21
armarx::navigation::client::Navigator::InjectedServices::navigator
core::NavigatorInterface * navigator
Definition: Navigator.h:122
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
events.h
armarx::navigation::client::Navigator::update
void update(const std::vector< core::Pose > &waypoints, core::NavigationFrame frame)
Definition: Navigator.cpp:81
armarx::navigation::client::Navigator::onWaypointReached
void onWaypointReached(const std::function< void(int)> &callback)
Definition: Navigator.cpp:163
armarx::navigation::client::StopEvent
Definition: Navigator.h:43
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:77
armarx::status
status
Definition: FiniteStateMachine.h:244
armarx::navigation::client::Navigator::Navigator
Navigator(const InjectedServices &services)
Definition: Navigator.cpp:25
PathBuilder.h
armarx::navigation::client::Navigator::resume
void resume()
Definition: Navigator.cpp:135
armarx::navigation::client::Navigator::moveToLocation
void moveToLocation(const std::string &location)
Definition: Navigator.cpp:105
armarx::navigation::client::Navigator::moveTowards
void moveTowards(const core::Direction &direction, core::NavigationFrame frame)
Definition: Navigator.cpp:90
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:52
armarx::navigation::client::Navigator::pause
void pause()
Definition: Navigator.cpp:127
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:181
armarx::navigation::core::Direction
Eigen::Vector3f Direction
Definition: basic_types.h:39
armarx::navigation::client::Navigator::stop
void stop()
Definition: Navigator.cpp:143
armarx::navigation::client::PathBuilder::path
const WaypointTargets & path() const
Definition: PathBuilder.cpp:35
Logging.h
armarx::navigation::core::NavigatorInterface::pause
virtual void pause()=0
armarx::navigation::core::NavigatorInterface::stop
virtual void stop()=0
types.h
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:42