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-2018, 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 "poses-precomp.h" // Precompiled headers
11 
12 #include <mrpt/poses/CPose2D.h>
13 #include <mrpt/poses/CPose3D.h>
15 #include <mrpt/system/datetime.h>
16 #include <mrpt/math/wrap2pi.h>
17 #include <mutex>
18 #include <iostream>
19 
20 using namespace mrpt;
21 using namespace mrpt::poses;
22 using namespace mrpt::math;
23 using namespace mrpt::system;
24 using namespace std;
25 
26 /* --------------------------------------------------------
27  Ctor
28  -------------------------------------------------------- */
30 /* --------------------------------------------------------
31  Dtor
32  -------------------------------------------------------- */
34 /* --------------------------------------------------------
35  reset
36  -------------------------------------------------------- */
38 {
39  std::lock_guard<std::mutex> lock(m_cs);
40 
41  m_last_loc_time.reset();
42  m_last_odo_time.reset();
43 
44  m_last_loc = TPose2D(0, 0, 0);
45  m_loc_odo_ref = TPose2D(0, 0, 0);
46  m_last_odo = TPose2D(0, 0, 0);
47 
48  m_robot_vel_local = TTwist2D(.0, .0, .0);
49 }
50 
51 /** Updates the filter so the pose is tracked to the current time */
53  const TPose2D& newPose, Clock::time_point cur_tim)
54 {
55  std::lock_guard<std::mutex> lock(m_cs);
56 
57  // Overwrite old localization data:
58  m_last_loc_time = cur_tim;
59  m_last_loc = newPose;
60 
61  // And create interpolated odometry data to work as "reference pose":
62  if (m_last_odo_time)
63  {
64  const double dT = timeDifference(m_last_odo_time.value(), cur_tim);
65  extrapolateRobotPose(m_last_odo, m_robot_vel_local, dT, m_loc_odo_ref);
66  }
67 }
68 
69 /** Updates the filter so the pose is tracked to the current time */
71  const TPose2D& newGlobalOdometry, Clock::time_point cur_tim, bool hasVelocities,
72  const mrpt::math::TTwist2D& velLocal)
73 {
75 
76  std::lock_guard<std::mutex> lock(m_cs);
77 
78  if (m_last_odo_time)
79  {
80  const double dT = timeDifference(m_last_odo_time.value(), cur_tim);
81  if (dT <= 0)
82  std::cerr << "[CRobot2DPoseEstimator::processUpdateNewOdometry] "
83  "WARNING: Diff. in timestamps between odometry should "
84  "be >0, and it's "
85  << dT << "\n";
86  }
87 
88  // First, update velocities:
89  if (hasVelocities)
90  {
91  m_robot_vel_local = velLocal;
92  }
93  else
94  { // Note: JLBC 23/Nov/2016: I have removed an estimation of velocity from
95  // increments of odometry
96  // because it was really bad. Just don't make up things: if the user
97  // doesn't provide us velocities,
98  // we don't use velocities.
99  m_robot_vel_local = TTwist2D(.0, .0, .0);
100  }
101 
102  // And now times & odo:
103  m_last_odo_time = cur_tim;
104  m_last_odo = newGlobalOdometry;
105 
106  MRPT_END
107 }
108 
110  mrpt::math::TPose2D& pose, mrpt::math::TTwist2D& velLocal,
111  mrpt::math::TTwist2D& velGlobal, mrpt::Clock::time_point tim_query) const
112 {
113  if (!m_last_odo_time || !m_last_loc_time)
114  return false;
115 
116  const double dTimeLoc = timeDifference(m_last_loc_time.value(), 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 =
122  (CPose2D(m_last_loc) + (CPose2D(m_last_odo) - CPose2D(m_loc_odo_ref)))
123  .asTPose();
124 
125  // Add the extrapolation:
126  const double dTimeOdo = timeDifference(m_last_odo_time.value(), tim_query);
127  if (dTimeOdo > params.max_odometry_age) return false;
128 
129  extrapolateRobotPose(p, m_robot_vel_local, dTimeOdo, pose);
130 
131  // Constant speed model:
132  velLocal = m_robot_vel_local;
133  velGlobal = velLocal;
134  velGlobal.rotate(pose.phi);
135 
136  return true;
137 }
138 
139 /** get the current estimate
140 * \return true is the estimate can be trusted. False if the real observed data
141 * is too old.
142 */
144 {
145  if (!m_last_odo_time && !m_last_loc_time)
146  {
147  pose = TPose2D(0, 0, 0);
148  return false;
149  }
150 
151  bool ret_odo;
152  if (m_last_odo_time && m_last_loc_time)
153  ret_odo = (m_last_odo_time.value() > m_last_loc_time.value());
154  else if (m_last_odo_time)
155  ret_odo = true;
156  else
157  ret_odo = false;
158 
159  if (ret_odo)
160  pose = (CPose2D(m_last_loc) +
161  (CPose2D(m_last_odo) - CPose2D(m_loc_odo_ref)))
162  .asTPose();
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 }
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:140
void rotate(const double ang)
Transform the (vx,vy) components for a counterclockwise rotation of ang radians.
#define MRPT_START
Definition: exceptions.h:262
double x
X,Y coordinates.
std::chrono::time_point< Clock > time_point
Definition: Clock.h:26
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:175
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.
void processUpdateNewOdometry(const mrpt::math::TPose2D &newGlobalOdometry, mrpt::Clock::time_point cur_tim, bool hasVelocities=false, const mrpt::math::TTwist2D &newRobotVelLocal=mrpt::math::TTwist2D())
Updates the filter with new odometry readings.
double vx
Velocity components: X,Y (m/s)
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
const GLdouble * v
Definition: glext.h:3678
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
bool getCurrentEstimate(mrpt::math::TPose2D &pose, mrpt::math::TTwist2D &velLocal, mrpt::math::TTwist2D &velGlobal, mrpt::Clock::time_point tim_query=mrpt::Clock::now()) const
Get the estimate for a given timestamp (defaults to now()), obtained as:
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:38
const float R
const double & phi() const
Get the phi angle of the 2D pose (in radians)
Definition: CPose2D.h:80
#define MRPT_END
Definition: exceptions.h:266
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.h:122
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...
void processUpdateNewPoseLocalization(const mrpt::math::TPose2D &newPose, mrpt::Clock::time_point tim)
Updates the filter with new global-coordinates localization data from a localization or SLAM source...
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: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020