selfdriving
VehicleMotionInterface.h
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------
2  * SelfDriving C++ library based on PTGs and mrpt-nav
3  * Copyright (C) 2019-2022 Jose Luis Blanco, University of Almeria
4  * See LICENSE for license information.
5  * ------------------------------------------------------------------------- */
6 
7 #pragma once
8 
12 #include <mrpt/kinematics/CVehicleVelCmd.h>
13 #include <mrpt/rtti/CObject.h>
14 #include <mrpt/system/COutputLogger.h>
15 
16 namespace mpp
17 {
18 using mrpt::kinematics::CVehicleVelCmd;
19 
20 enum class STOP_TYPE : uint8_t
21 {
22  REGULAR = 0,
23  EMERGENCY
24 };
25 
26 /** The virtual interface between a path follower / plan executor and a real
27  * mobile platform (vehicle, robot), regarding controlling its motion.
28  *
29  * To enable the use of this library with a new robot, the user must define
30  * a new class derived from this virtual class and implement all pure virtual
31  * and the desired virtual methods according to the docs below.
32  *
33  * This class does not make assumptions about the kinematic model of the robot,
34  * so it can work with either Ackermann, differential-driven or
35  * holonomic robots. It will depend on the used PTGs, so checkout each PTG
36  * documentation for the lenght and meaning of velocity commands.
37  *
38  * Assumptions: The platform...
39  * - has a global localization system (e.g. particle filter) with
40  * respect to some fixed global frame of reference `map`, see
41  * get_localization().
42  * - has odometry with a fixed global frame of reference `odom`, see
43  * get_odometry().
44  * - is able to execute motion primitives according to one or more PTGs,
45  * - is able to keep one immediately-running motion primitive and optionally
46  * another one in a queue, which will be executed when a given condition
47  * holds; see motion_execute(). This mechanism ensures accurately path
48  * following without computer-robot communication delays affecting the plan.
49  *
50  *
51  */
52 class VehicleMotionInterface : public mrpt::system::COutputLogger,
53  public mrpt::rtti::CObject
54 {
55  DEFINE_VIRTUAL_MRPT_OBJECT(VehicleMotionInterface)
56 
57  public:
59  : mrpt::system::COutputLogger("VehicleMotionInterface")
60  {
61  }
62  virtual ~VehicleMotionInterface();
63 
64  /** Provides access to the vehicle localization data.
65  *
66  * The implementation should not take too much time to return, so if it
67  * might take more than ~10ms to ask the robot for the instantaneous data,
68  * it may be good enough to return the latest cached values, updated in a
69  * parallel thread.
70  *
71  * In case of a hardware/communication error, leave `valid=false` in the
72  * return structure.
73  */
74  virtual VehicleLocalizationState get_localization() = 0;
75 
76  /** Provides access to the vehicle odometry data.
77  *
78  *
79  * The implementation should not take too much time to return, so if it
80  * might take more than ~10ms to ask the robot for the instantaneous data,
81  * it may be good enough to return the latest cached values, updated in a
82  * parallel thread.
83  *
84  * In case of a hardware/communication error, leave `valid=false` in the
85  * return structure.
86  */
87  virtual VehicleOdometryState get_odometry() = 0;
88 
89  /** Sends a motion command to the vehicle "immediate" and "next" slots.
90  *
91  * A vehicle may accept one or more different implementation-specific
92  * CVehicleVelCmd classes.
93  *
94  * This method resets the watchdog timer started with startWatchdog()
95  *
96  * The vehicle should be able to execute a motion primitive ("immediate"
97  * slot) and holding a pending one ("next" slot) which will be moved to the
98  * immediate slot when a given condition holds, leaving the "next" slot
99  * free.
100  *
101  * Possible combinations of calls to this method:
102  *
103  * 1) `immediate` set, `next` not set: replaces whatever the vehicle was
104  * doing and executes the given immediate command, dropping possible former
105  * immediate and next commands.
106  *
107  * 2) `immediate` set, `next` set: replaces both vehicle execution "slots"
108  * with the given commands.
109  *
110  * 3) `immediate` not set, `next` set: should be received by a vehicle only
111  * while there is an "immediate" motion command under execution, and the
112  * "next" slot is free. This stores a new "next" motion command, leaving the
113  * currently-executing one untouched. When the "next condition" holds true,
114  * the "next" slot will replace the "immediate" slot and "next" will be free
115  * again.
116  *
117  * 4) `immediate` not set, `next` not set: This is a "NOP" motion command,
118  * which does not change anything but let the vehicle platform know that
119  * there is someone in charge checking the path following and the way is
120  * obstacles free and safe to keep moving.
121  *
122  *
123  * \return false on any error.
124  * \sa startWatchdog(), supports_enqeued_motions()
125  */
126  virtual bool motion_execute(
127  const std::optional<CVehicleVelCmd::Ptr>& immediate,
128  const std::optional<EnqueuedMotionCmd>& next) = 0;
129 
130  /** Reimplement to return true if enqueued motions are supported in
131  * motion_execute()
132  */
133  virtual bool supports_enqeued_motions() const { return false; }
134 
135  /** Reimplement to return true if an enqueued motions has been received from
136  * motion_execute() and it is still waiting to be executed, or false
137  * otherwise (no action enqeued, or it was already triggered and executed).
138  */
139  virtual bool enqeued_motion_pending() const { return false; }
140 
141  /** Reimplement to return true if an enqueued motions has been received from
142  * motion_execute() and it has timed out, or false
143  * otherwise (no action enqeued, or it was already triggered correctly).
144  */
145  virtual bool enqeued_motion_timed_out() const { return false; }
146 
147  /** Reimplement to return the exact odometry value at the precise moment
148  * that the last enqueued motion was executed by the vehicle motion
149  * controller. The `optional<>` should be empty only if no enqueued motion
150  * has been executed yet.
151  */
152  virtual std::optional<VehicleOdometryState>
154  {
155  return {};
156  }
157 
158  /** Stops the vehicle. Different levels of abruptness in the stop can be
159  * considered given the emergency condition or not of the command.
160  */
161  virtual void stop(const STOP_TYPE stopType) = 0;
162 
163  virtual void stop_watchdog()
164  {
165  MRPT_LOG_INFO("Default stop_watchdog() called.");
166  }
167  virtual void start_watchdog(
168  [[maybe_unused]] const size_t periodMilliseconds)
169  {
170  MRPT_LOG_INFO("Default start_watchdog() called.");
171  }
172 
173  /** Returns clockwall time (UNIX timestamp as double) for real robots
174  * [default], simulated time in simulators. */
175  virtual double robot_time() const { return mrpt::Clock::nowDouble(); }
176 
177  /** @name Event callbacks
178  * @{ */
179 
180  /**
181  * @brief Callback if current navigation ended due to some error
182  */
183  virtual void on_nav_end_due_to_error()
184  {
185  MRPT_LOG_WARN("Default on_nav_end_due_to_error() called.");
186  }
187 
188  /**
189  * @brief Callback upon starting a new waypointsequence navigation
190  */
191  virtual void on_nav_start()
192  {
193  MRPT_LOG_WARN("Default on_nav_start() event handler called.");
194  }
195 
196  /**
197  * @brief Callback if navigation ended by an accepted trigger or reached the
198  * last specified waypoint
199  */
200  virtual void on_nav_end()
201  {
202  MRPT_LOG_WARN("Default on_nav_end() event handler called.");
203  }
204 
205  /**
206  * @brief Callback for when NavEngine cannot make progress to get
207  * increasingly closer to the final target during a certain period of time.
208  * It may indicate that the high-level path the vehicle is trying to follow
209  * is no longer valid due to a blocked way. On your user side, you could
210  * call NavEngine::cancel() and/or re-compute an alternative path and issue
211  * a new set of navigation waypoints or just report the error to the user.
212  *
213  * \sa NavEngine::Configuration::timeoutNotGettingCloserGoal
214  */
215  virtual void on_path_seems_blocked()
216  {
217  MRPT_LOG_WARN("Default on_path_seems_blocked() event handler called.");
218  }
219 
220  /**
221  * @brief Callback when the NavEngine *predicts* a collision with an
222  * obstacle and needed to issue a stop command.
223  */
224  virtual void on_apparent_collision()
225  {
226  MRPT_LOG_WARN("Default on_apparent_collision() event handler called.");
227  }
228  /**
229  * @brief Callback upon reaching a waypoint in a waypoint sequeunce.
230  * Mostly used for logging
231  * @param waypoint_index index of waypoint in the sequence
232  * @param reached_skipped whether it was reached(true) or skipped (false)
233  */
234  virtual void on_waypoint_reached(
235  const size_t waypoint_index, bool reached_skipped)
236  {
237  MRPT_LOG_WARN_FMT(
238  "Default on_waypoint_reached() index = %zu event "
239  "handler called (event='%s').",
240  waypoint_index, reached_skipped ? "reached" : "skipped");
241  }
242 
243  /**
244  * @brief Callback when NavEngine cannot reach a specified target location
245  * because there are obstacles at the specified target
246  */
248  {
249  MRPT_LOG_WARN("Default on_apparent_collision() event handler called.");
250  }
251 
252  /** @} */
253 };
254 
255 } // namespace mpp
Definition: VehicleOdometryState.h:18
virtual void on_nav_start()
Callback upon starting a new waypointsequence navigation.
Definition: VehicleMotionInterface.h:191
virtual bool enqeued_motion_timed_out() const
Definition: VehicleMotionInterface.h:145
virtual void stop_watchdog()
Definition: VehicleMotionInterface.h:163
Definition: VehicleMotionInterface.h:52
virtual void on_nav_end()
Callback if navigation ended by an accepted trigger or reached the last specified waypoint...
Definition: VehicleMotionInterface.h:200
Definition: bestTrajectory.h:15
virtual void on_path_seems_blocked()
Callback for when NavEngine cannot make progress to get increasingly closer to the final target durin...
Definition: VehicleMotionInterface.h:215
virtual void on_cannot_get_closer_to_blocked_target()
Callback when NavEngine cannot reach a specified target location because there are obstacles at the s...
Definition: VehicleMotionInterface.h:247
virtual bool supports_enqeued_motions() const
Definition: VehicleMotionInterface.h:133
virtual void on_apparent_collision()
Callback when the NavEngine predicts a collision with an obstacle and needed to issue a stop command...
Definition: VehicleMotionInterface.h:224
VehicleMotionInterface()
Definition: VehicleMotionInterface.h:58
virtual std::optional< VehicleOdometryState > enqued_motion_last_odom_when_triggered() const
Definition: VehicleMotionInterface.h:153
virtual void start_watchdog([[maybe_unused]] const size_t periodMilliseconds)
Definition: VehicleMotionInterface.h:167
virtual void on_waypoint_reached(const size_t waypoint_index, bool reached_skipped)
Callback upon reaching a waypoint in a waypoint sequeunce. Mostly used for logging.
Definition: VehicleMotionInterface.h:234
virtual bool enqeued_motion_pending() const
Definition: VehicleMotionInterface.h:139
virtual void on_nav_end_due_to_error()
Callback if current navigation ended due to some error.
Definition: VehicleMotionInterface.h:183
STOP_TYPE
Definition: VehicleMotionInterface.h:20
virtual double robot_time() const
Definition: VehicleMotionInterface.h:175
Definition: VehicleLocalizationState.h:20