Main MRPT website > C++ reference for MRPT 1.9.9
CRobot2DPoseEstimator.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/poses/CPose2D.h>
13 #include <mrpt/poses/CPose3D.h>
15 #include <mrpt/math/wrap2pi.h>
16 #include <mutex>
17 
18 using namespace mrpt;
19 using namespace mrpt::poses;
20 using namespace mrpt::math;
21 using namespace mrpt::utils;
22 using namespace mrpt::system;
23 using namespace std;
24 
25 /* --------------------------------------------------------
26  Ctor
27  -------------------------------------------------------- */
29 /* --------------------------------------------------------
30  Dtor
31  -------------------------------------------------------- */
33 /* --------------------------------------------------------
34  reset
35  -------------------------------------------------------- */
37 {
38  std::lock_guard<std::mutex> lock(m_cs);
39 
40  m_last_loc_time = INVALID_TIMESTAMP;
41  m_last_odo_time = INVALID_TIMESTAMP;
42 
43  m_last_loc = TPose2D(0, 0, 0);
44  m_loc_odo_ref = TPose2D(0, 0, 0);
45  m_last_odo = TPose2D(0, 0, 0);
46 
47  m_robot_vel_local = TTwist2D(.0, .0, .0);
48 }
49 
50 /** Updates the filter so the pose is tracked to the current time */
52  const TPose2D& newPose, TTimeStamp cur_tim)
53 {
54  std::lock_guard<std::mutex> lock(m_cs);
55 
56  // Overwrite old localization data:
57  m_last_loc_time = cur_tim;
58  m_last_loc = newPose;
59 
60  // And create interpolated odometry data to work as "reference pose":
61  if (m_last_odo_time != INVALID_TIMESTAMP)
62  {
63  const double dT = timeDifference(m_last_odo_time, cur_tim);
64  extrapolateRobotPose(m_last_odo, m_robot_vel_local, dT, m_loc_odo_ref);
65  }
66 }
67 
68 /** Updates the filter so the pose is tracked to the current time */
70  const TPose2D& newGlobalOdometry, TTimeStamp cur_tim, bool hasVelocities,
71  const mrpt::math::TTwist2D& velLocal)
72 {
74 
75  std::lock_guard<std::mutex> lock(m_cs);
76 
77  if (m_last_odo_time != INVALID_TIMESTAMP)
78  {
79  const double dT = timeDifference(m_last_odo_time, cur_tim);
80  if (dT <= 0)
81  std::cerr << "[CRobot2DPoseEstimator::processUpdateNewOdometry] "
82  "WARNING: Diff. in timestamps between odometry should "
83  "be >0, and it's "
84  << dT << "\n";
85  }
86 
87  // First, update velocities:
88  if (hasVelocities)
89  {
90  m_robot_vel_local = velLocal;
91  }
92  else
93  { // Note: JLBC 23/Nov/2016: I have removed an estimation of velocity from
94  // increments of odometry
95  // because it was really bad. Just don't make up things: if the user
96  // doesn't provide us velocities,
97  // we don't use velocities.
98  m_robot_vel_local = TTwist2D(.0, .0, .0);
99  }
100 
101  // And now times & odo:
102  m_last_odo_time = cur_tim;
103  m_last_odo = newGlobalOdometry;
104 
105  MRPT_END
106 }
107 
109  mrpt::math::TPose2D& pose, mrpt::math::TTwist2D& velLocal,
110  mrpt::math::TTwist2D& velGlobal, mrpt::system::TTimeStamp tim_query) const
111 {
112  if (m_last_odo_time == INVALID_TIMESTAMP ||
113  m_last_loc_time == INVALID_TIMESTAMP)
114  return false;
115 
116  const double dTimeLoc = timeDifference(m_last_loc_time, tim_query);
117  if (dTimeLoc > params.max_localiz_age) return false;
118 
119  // Overall estimate:
120  // last_loc (+) [ last_odo (-) odo_ref ] (+) extrapolation_from_vw
121  const TPose2D p = TPose2D(
122  CPose2D(m_last_loc) + (CPose2D(m_last_odo) - CPose2D(m_loc_odo_ref)));
123 
124  // Add the extrapolation:
125  const double dTimeOdo = timeDifference(m_last_odo_time, tim_query);
126  if (dTimeOdo > params.max_odometry_age) return false;
127 
128  extrapolateRobotPose(p, m_robot_vel_local, dTimeOdo, pose);
129 
130  // Constant speed model:
131  velLocal = m_robot_vel_local;
132  velGlobal = velLocal;
133  velGlobal.rotate(pose.phi);
134 
135  return true;
136 }
137 
138 /** get the current estimate
139 * \return true is the estimate can be trusted. False if the real observed data
140 * is too old.
141 */
143 {
144  if (m_last_odo_time == INVALID_TIMESTAMP &&
145  m_last_loc_time == INVALID_TIMESTAMP)
146  {
147  pose = TPose2D(0, 0, 0);
148  return false;
149  }
150 
151  bool ret_odo;
152  if (m_last_odo_time != INVALID_TIMESTAMP &&
153  m_last_loc_time != INVALID_TIMESTAMP)
154  ret_odo = (m_last_odo_time > m_last_loc_time);
155  else if (m_last_odo_time != INVALID_TIMESTAMP)
156  ret_odo = true;
157  else
158  ret_odo = false;
159 
160  if (ret_odo)
161  pose = CPose2D(m_last_loc) +
162  (CPose2D(m_last_odo) - CPose2D(m_loc_odo_ref));
163  else
164  pose = m_last_loc;
165 
166  return true;
167 }
168 
169 // An auxiliary method to extrapolate the pose of a robot located at "p"
170 // with velocities (v,w) after a time delay "delta_time".
172  const TPose2D& p, const mrpt::math::TTwist2D& velLocal,
173  const double delta_time, TPose2D& new_p)
174 {
175  if (velLocal.vx == 0 && velLocal.vy == 0 && velLocal.omega == 0)
176  { // Still
177  new_p = p;
178  }
179  else if (std::abs(velLocal.vy) > 1e-2)
180  { // non-Ackermann-like vehicle: extrapolate as a straight line:
181  const TPoint2D dp =
182  TPoint2D(delta_time * velLocal.vx, delta_time * velLocal.vy);
183  TPoint2D pg;
184  CPose2D(p).composePoint(dp, pg);
185  new_p.x = pg.x;
186  new_p.y = pg.y;
187  new_p.phi = p.phi + delta_time * velLocal.omega;
188  }
189  else
190  {
191  // vy==0, assume we are in a Ackermann-like steering vehicle: compute an
192  // arc:
193  const double R = velLocal.vx / velLocal.omega; // Radius
194  const double theta = velLocal.omega * delta_time; // traversed arc
195  const double cc = cos(p.phi);
196  const double ss = sin(p.phi);
197 
198  const double arc_x = R * sin(theta);
199  const double arc_y = R * (1 - cos(theta));
200 
201  new_p.x = p.x + cc * arc_x - ss * arc_y;
202  new_p.y = p.y + ss * arc_x + cc * arc_y;
203  new_p.phi = p.phi + theta;
204  }
205 }
206 
208 {
210  bool v = getLatestRobotPose(p);
211  if (v)
212  {
213  pose.x(p.x);
214  pose.y(p.y);
215  pose.phi(p.phi);
216  }
217  return v;
218 }
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
Definition: datetime.h:32
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:135
void rotate(const double ang)
Transform the (vx,vy) components for a counterclockwise rotation of ang radians.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
double x
X,Y coordinates.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
double x
X,Y coordinates.
bool getLatestRobotPose(mrpt::math::TPose2D &pose) const
Get the latest known robot pose, either from odometry or localization.
STL namespace.
void composePoint(double lx, double ly, double &gx, double &gy) const
An alternative, slightly more efficient way of doing with G and L being 2D points and P this 2D pose...
Definition: CPose2D.cpp:188
void reset()
Resets all internal state.
2D twist: 2D velocity vector (vx,vy) + planar angular velocity (omega)
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
#define MRPT_END
void processUpdateNewPoseLocalization(const mrpt::math::TPose2D &newPose, mrpt::system::TTimeStamp tim)
Updates the filter with new global-coordinates localization data from a localization or SLAM source...
double vx
Velocity components: X,Y (m/s)
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
Definition: datetime.h:16
void processUpdateNewOdometry(const mrpt::math::TPose2D &newGlobalOdometry, mrpt::system::TTimeStamp cur_tim, bool hasVelocities=false, const mrpt::math::TTwist2D &newRobotVelLocal=mrpt::math::TTwist2D())
Updates the filter with new odometry readings.
#define MRPT_START
const GLdouble * v
Definition: glext.h:3678
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:40
const float R
bool getCurrentEstimate(mrpt::math::TPose2D &pose, mrpt::math::TTwist2D &velLocal, mrpt::math::TTwist2D &velGlobal, mrpt::system::TTimeStamp tim_query=mrpt::system::now()) const
Get the estimate for a given timestamp (defaults to now()), obtained as:
const double & phi() const
Get the phi angle of the 2D pose (in radians)
Definition: CPose2D.h:91
GLboolean reset
Definition: glext.h:3582
Lightweight 2D pose.
double timeDifference(const mrpt::system::TTimeStamp t_first, const mrpt::system::TTimeStamp t_later)
Returns the time difference from t1 to t2 (positive if t2 is posterior to t1), in seconds...
Definition: datetime.cpp:208
static void extrapolateRobotPose(const mrpt::math::TPose2D &p, const mrpt::math::TTwist2D &robot_vel_local, const double delta_time, mrpt::math::TPose2D &new_p)
An auxiliary method to extrapolate the pose of a robot located at "p" with velocities (v...
Lightweight 2D point.
GLfloat GLfloat p
Definition: glext.h:6305
GLenum const GLfloat * params
Definition: glext.h:3534
double phi
Orientation (rads)
double omega
Angular velocity (rad/s)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019