21 #if MRPT_HAS_WXWIDGETS
23 #include <wx/msgdlg.h>
24 #include <wx/string.h>
25 #include <wx/progdlg.h>
26 #include <wx/busyinfo.h>
58 #if MRPT_HAS_WXWIDGETS
60 std::unique_ptr<wxBusyCursor> waitCursorPtr;
62 waitCursorPtr = std::unique_ptr<wxBusyCursor>(
new wxBusyCursor());
73 set<string> lstGPSLabels;
83 if (outInfo) *outInfo = outInfoTemp;
85 map<string, map<TTimeStamp, TPoint3D>>
89 bool ref_valid =
false;
100 ref_valid = !
ref.isClear();
103 const double std_0 = memFil.
read_double(
"CONSISTENCY_TEST",
"std_0", 0);
104 bool doConsistencyCheck = std_0 > 0;
108 const bool doUncertaintyCovs =
size(outInfoTemp.
W_star, 1) != 0;
109 if (doUncertaintyCovs &&
112 "ERROR: W_star matrix for uncertainty estimation is provided but "
113 "it's not a 6x6 matrix.");
118 #if MRPT_HAS_WXWIDGETS
119 wxProgressDialog* progDia =
nullptr;
122 progDia =
new wxProgressDialog(
123 wxT(
"Building map"), wxT(
"Getting GPS observations..."),
124 (
int)(last -
first + 1),
126 wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE |
127 wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME);
133 std::map<std::string, CObservationGPS::Ptr>>
135 TListGPSs list_gps_obs;
137 map<string, size_t> GPS_RTK_reads;
138 map<string, TPoint3D>
139 GPS_local_coords_on_vehicle;
141 for (i =
first; !abort && i <= last; i++)
148 case CRawlog::etObservation:
155 std::dynamic_pointer_cast<CObservationGPS>(o);
157 if (obs->has_GGA_datum &&
162 list_gps_obs[obs->timestamp][obs->sensorLabel] = obs;
164 lstGPSLabels.insert(obs->sensorLabel);
168 if (obs->has_GGA_datum &&
174 GPS_RTK_reads[obs->sensorLabel]++;
178 if (GPS_local_coords_on_vehicle.find(
180 GPS_local_coords_on_vehicle.end())
181 GPS_local_coords_on_vehicle[obs->sensorLabel] =
187 gps_paths[obs->sensorLabel][obs->timestamp] =
TPoint3D(
201 if ((
count++ % 100) == 0)
203 #if MRPT_HAS_WXWIDGETS
206 if (!progDia->Update((
int)(i -
first))) abort =
true;
213 #if MRPT_HAS_WXWIDGETS
227 map<set<string>,
double> Ad_ij;
228 map<set<string>,
double>
232 map<size_t, string> D_cov_rev_indexes;
238 if (doConsistencyCheck && GPS_local_coords_on_vehicle.size() == 3)
240 unsigned int cnt = 0;
242 GPS_local_coords_on_vehicle.begin();
243 i != GPS_local_coords_on_vehicle.end(); ++i)
246 D_cov_indexes[i->first] = cnt;
247 D_cov_rev_indexes[cnt] = i->first;
251 j != GPS_local_coords_on_vehicle.end(); ++j)
258 phi_ij[
make_set(i->first, j->first)] =
259 atan2(pj.
y - pi.
y, pj.
x - pi.
x);
263 ASSERT_(D_cov_indexes.size() == 3 && D_cov_rev_indexes.size() == 3);
265 D_cov.setSize(D_cov_indexes.size(), D_cov_indexes.size());
266 D_mean.resize(D_cov_indexes.size());
273 square(Ad_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[1])]);
276 square(Ad_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[2])]);
279 square(Ad_ij[
make_set(D_cov_rev_indexes[1], D_cov_rev_indexes[2])]);
282 Ad_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[1])] *
283 Ad_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[2])] *
284 cos(phi_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[1])] -
285 phi_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[2])]);
286 D_cov(0, 1) = D_cov(1, 0);
289 -Ad_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[1])] *
290 Ad_ij[
make_set(D_cov_rev_indexes[1], D_cov_rev_indexes[2])] *
291 cos(phi_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[1])] -
292 phi_ij[
make_set(D_cov_rev_indexes[1], D_cov_rev_indexes[2])]);
293 D_cov(0, 2) = D_cov(2, 0);
296 Ad_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[2])] *
297 Ad_ij[
make_set(D_cov_rev_indexes[1], D_cov_rev_indexes[2])] *
298 cos(phi_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[2])] -
299 phi_ij[
make_set(D_cov_rev_indexes[1], D_cov_rev_indexes[2])]);
300 D_cov(1, 2) = D_cov(2, 1);
302 D_cov *= 4 *
square(std_0);
304 D_cov_1 = D_cov.inv();
309 square(Ad_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[1])]);
311 square(Ad_ij[
make_set(D_cov_rev_indexes[0], D_cov_rev_indexes[2])]);
313 square(Ad_ij[
make_set(D_cov_rev_indexes[1], D_cov_rev_indexes[2])]);
316 doConsistencyCheck =
false;
321 int N_GPSs = list_gps_obs.size();
327 if (list_gps_obs.size() > 4)
340 std::map<std::string, CObservationGPS::Ptr>& GPS = i->second;
344 l != lstGPSLabels.end(); ++l)
347 bool fnd = (GPS.find(*l) != GPS.end());
360 if (i_b1->second.find(*l) != i_b1->second.end())
361 GPS_b1 = i_b1->second.find(*l)->second;
363 if (i_a1->second.find(*l) != i_a1->second.end())
364 GPS_a1 = i_a1->second.find(*l)->second;
366 if (!disableGPSInterp && GPS_a1 && GPS_b1)
369 GPS_b1->timestamp, GPS_a1->timestamp) < 0.5)
373 new_gps->sensorLabel = *l;
383 .fields.longitude_degrees =
388 .fields.longitude_degrees);
390 .fields.latitude_degrees =
395 .fields.latitude_degrees);
397 .fields.altitude_meters =
402 .fields.altitude_meters);
405 (GPS_a1->timestamp + GPS_b1->timestamp) / 2;
407 i->second[new_gps->sensorLabel] = new_gps;
414 #if MRPT_HAS_WXWIDGETS
415 wxProgressDialog* progDia3 =
nullptr;
418 progDia3 =
new wxProgressDialog(
419 wxT(
"Building map"), wxT(
"Estimating 6D path..."),
422 wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE |
423 wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
424 wxPD_REMAINING_TIME);
431 i != list_gps_obs.end(); ++i, idx_in_GPSs++)
434 if (i->second.size() >= 3)
436 const size_t N = i->second.size();
437 std::map<std::string, CObservationGPS::Ptr>& GPS = i->second;
439 std::map<string, size_t>
448 .getAsStruct<TGeodeticCoords>();
456 for (k = 0, g_it = GPS.begin(); g_it != GPS.end(); ++g_it, ++k)
466 string(
"OFFSET_") + g_it->second->sensorLabel;
471 XYZidxs[g_it->second->sensorLabel] =
479 g_it->second->sensorPose.x(),
480 g_it->second->sensorPose.y(),
481 g_it->second->sensorPose
490 if (doConsistencyCheck && GPS.size() == 3)
501 X[XYZidxs[D_cov_rev_indexes[0]]],
502 Y[XYZidxs[D_cov_rev_indexes[0]]],
503 Z[XYZidxs[D_cov_rev_indexes[0]]]);
505 X[XYZidxs[D_cov_rev_indexes[1]]],
506 Y[XYZidxs[D_cov_rev_indexes[1]]],
507 Z[XYZidxs[D_cov_rev_indexes[1]]]);
509 X[XYZidxs[D_cov_rev_indexes[2]]],
510 Y[XYZidxs[D_cov_rev_indexes[2]]],
511 Z[XYZidxs[D_cov_rev_indexes[2]]]);
518 iGPSdist2, D_mean, D_cov_1);
528 double optimal_scale;
533 corrs, optimal_pose, optimal_scale,
true);
548 robot_path.
insert(i->first, veh_pose);
551 if (doUncertaintyCovs)
555 final_veh_uncert.
cov = outInfoTemp.
W_star;
561 final_veh_uncert.
cov;
566 if ((
count++ % 100) == 0)
568 #if MRPT_HAS_WXWIDGETS
571 if (!progDia3->Update(idx_in_GPSs)) abort =
true;
578 #if MRPT_HAS_WXWIDGETS
586 if (PATH_SMOOTH_FILTER > 0 && robot_path.
size() > 1)
592 const double MAX_DIST_TO_FILTER = 4.0;
594 for (
auto i = robot_path.
begin(); i != robot_path.
end(); ++i)
600 pitchs.push_back(
p.pitch);
601 rolls.push_back(
p.roll);
605 k < PATH_SMOOTH_FILTER &&
q != robot_path.
begin(); k++)
611 pitchs.push_back(
q->second.pitch);
612 rolls.push_back(
q->second.roll);
617 k < PATH_SMOOTH_FILTER &&
q != (--robot_path.
end()); k++)
623 pitchs.push_back(
q->second.pitch);
624 rolls.push_back(
q->second.roll);
632 filtered_robot_path.
insert(i->first,
p);
635 robot_path = filtered_robot_path;
648 i != GPS_RTK_reads.end(); ++i)
650 if (i->second > bestNum)
653 bestLabel = i->first;
660 const string sect =
string(
"OFFSET_") + bestLabel;
661 const double off_X = memFil.
read_double(sect,
"x", 0);
662 const double off_Y = memFil.
read_double(sect,
"y", 0);
663 const double off_Z = memFil.
read_double(sect,
"z", 0);
686 if (outInfo) *outInfo = outInfoTemp;
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
T z() const
Return z coordinate of the quaternion.
T x() const
Return x coordinate of the quaternion.
T r() const
Return r coordinate of the quaternion.
T y() const
Return y coordinate of the quaternion.
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction.
This class stores messages from GNSS or GNSS+IMU devices, from consumer-grade inexpensive GPS receive...
std::shared_ptr< CObservationGPS > Ptr
std::shared_ptr< CObservation > Ptr
This class stores a rawlog (robotic datasets) in one of two possible formats:
CObservation::Ptr getAsObservation(size_t index) const
Returns the i'th element in the sequence, as being an observation, where index=0 is the first object.
void getCommentTextAsConfigFile(mrpt::utils::CConfigFileMemory &memCfg) const
Saves the block of comment text for the rawlog into the passed config file object.
size_t size() const
Returns the number of actions / observations object in the sequence.
TEntryType getType(size_t index) const
Returns the type of a given element.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
void setFromValues(const double x0, const double y0, const double z0, const double yaw=0, const double pitch=0, const double roll=0)
Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes...
This class stores a time-stamped trajectory in SE(3) (CPose3D poses).
Declares a class that represents a Probability Density function (PDF) of a 3D pose .
void changeCoordinatesReference(const CPose3D &newReferenceBase) override
this = p (+) this.
CPose3D mean
The mean value.
mrpt::math::CMatrixDouble66 cov
The 6x6 covariance matrix.
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,...
mrpt::math::CQuaternionDouble & quat()
Read/Write access to the quaternion representing the 3D rotation.
void setMaxTimeInterpolation(double time)
Set value of the maximum time to consider interpolation.
void insert(mrpt::system::TTimeStamp t, const pose_t &p)
Inserts a new pose in the sequence.
void clear()
Clears the current sequence of poses.
void setInterpolationMethod(TInterpolatorMethod method)
Change the method used to interpolate the robot path.
double x() const
Common members of all points & poses classes.
void read_matrix(const std::string §ion, const std::string &name, MATRIX_TYPE &outMatrix, const MATRIX_TYPE &defaultMatrix=MATRIX_TYPE(), bool failIfNotFound=false) const
Reads a configuration parameter as a matrix written in a matlab-like format - for example: "[2 3 4 ; ...
double read_double(const std::string §ion, const std::string &name, double defaultValue, bool failIfNotFound=false) const
This class implements a config file-like interface over a memory-stored string list.
GLuint GLuint GLsizei count
GLsizei const GLchar ** string
GLdouble GLdouble GLdouble GLdouble q
bool se3_l2(const mrpt::utils::TMatchingPairList &in_correspondences, mrpt::poses::CPose3DQuat &out_transform, double &out_scale, bool forceScaleToUnity=false)
Least-squares (L2 norm) solution to finding the optimal SE(3) transform between two reference frames ...
void geodeticToENU_WGS84(const TGeodeticCoords &in_coords, mrpt::math::TPoint3D &out_ENU_point, const TGeodeticCoords &in_coords_origin)
Coordinates transformation from longitude/latitude/height to ENU (East-North-Up) X/Y/Z coordinates Th...
void path_from_rtk_gps(mrpt::poses::CPose3DInterpolator &robot_path, const mrpt::obs::CRawlog &rawlog, size_t rawlog_first, size_t rawlog_last, bool isGUI=false, bool disableGPSInterp=false, int path_smooth_filter_size=2, TPathFromRTKInfo *outInfo=nullptr)
Reconstruct the path of a vehicle equipped with 3 RTK GPSs.
VECTORLIKE1::Scalar mahalanobisDistance(const VECTORLIKE1 &X, const VECTORLIKE2 &MU, const MAT &COV)
Computes the mahalanobis distance of a vector X given the mean MU and the covariance inverse COV_inv.
double averageWrap2Pi(const CVectorDouble &angles)
Computes the average of a sequence of angles in radians taking into account the correct wrapping in t...
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
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.
#define THROW_EXCEPTION(msg)
#define MRPT_CHECK_NORMAL_NUMBER(val)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
This base provides a set of functions for maths stuff.
T square(const T x)
Inline function for the square of a number.
This namespace contains representation of robot actions and observations.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
This namespace provides a OS-independent interface to many useful functions: filenames manipulation,...
This namespace provides topography helper functions, coordinate transformations.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::set< T > make_set(const T &v0, const T &v1)
double distanceTo(const TPoint3D &p) const
Point-to-point distance.
double x
X,Y,Z coordinates.
double sqrDistanceTo(const TPoint3D &p) const
Point-to-point distance, squared.
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
uint8_t fix_quality
NMEA standard values: 0 = invalid, 1 = GPS fix (SPS), 2 = DGPS fix, 3 = PPS fix, 4 = Real Time Kinema...
double altitude_meters
The measured altitude, in meters (A).
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
TGEODETICCOORDS getAsStruct() const
Return the geodetic coords as a mrpt::topography::TGeodeticCoords structure (requires linking against...
content_t fields
Message content, accesible by individual fields.
A set of geodetic coordinates: latitude, longitude and height, defined over a given geoid (typically,...
Used to return optional information from mrpt::topography::path_from_rtk_gps.
mrpt::math::CMatrixDouble W_star
The reference covariance matrix used to compute vehicle_uncertainty.
std::map< mrpt::system::TTimeStamp, mrpt::math::TPoint3D > best_gps_path
the path of the "best" GPS.
std::map< mrpt::system::TTimeStamp, double > mahalabis_quality_measure
A measure of the quality at each point (may be empty if not there is no enough information).
mrpt::aligned_containers< mrpt::system::TTimeStamp, mrpt::math::CMatrixDouble66 >::map_t vehicle_uncertainty
The 6x6 covariance matrix for the uncertainty of each vehicle pose (may be empty if there is no W_sta...
A structure for holding correspondences between two sets of points or points-like entities in 2D or 3...