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> 28 #endif // MRPT_HAS_WXWIDGETS 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:
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;
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
mrpt::math::CQuaternionDouble & quat()
Read/Write access to the quaternion representing the 3D rotation.
double x() const
Common members of all points & poses classes.
GLuint GLuint GLsizei count
double averageWrap2Pi(const CVectorDouble &angles)
Computes the average of a sequence of angles in radians taking into account the correct wrapping in t...
uint8_t fix_quality
NMEA standard values: 0 = invalid, 1 = GPS fix (SPS), 2 = DGPS fix, 3 = PPS fix, 4 = Real Time Kinema...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
CPose3D mean
The mean value.
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
T y() const
Return y coordinate of the quaternion.
#define MRPT_CHECK_NORMAL_NUMBER(val)
#define THROW_EXCEPTION(msg)
GLdouble GLdouble GLdouble GLdouble q
A set of geodetic coordinates: latitude, longitude and height, defined over a given geoid (typically...
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
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 setInterpolationMethod(TInterpolatorMethod method)
Change the method used to interpolate the robot path.
Used to return optional information from mrpt::topography::path_from_rtk_gps.
T square(const T x)
Inline function for the square of a number.
This class implements a config file-like interface over a memory-stored string list.
double altitude_meters
The measured altitude, in meters (A).
This base provides a set of functions for maths stuff.
void insert(mrpt::system::TTimeStamp t, const pose_t &p)
Inserts a new pose in the sequence.
T r() const
Return r coordinate of the quaternion.
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).
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
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 ; ...
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
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...
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...
double distanceTo(const TPoint3D &p) const
Point-to-point distance.
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
This class stores a rawlog (robotic datasets) in one of two possible formats:
This namespace contains representation of robot actions and observations.
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 ...
double x
X,Y,Z coordinates.
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,qz).
std::shared_ptr< CObservation > Ptr
void setMaxTimeInterpolation(double time)
Set value of the maximum time to consider interpolation.
GLsizei const GLchar ** string
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
mrpt::math::CMatrixDouble66 cov
The 6x6 covariance matrix.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
T x() const
Return x coordinate of the quaternion.
void clear()
Clears the current sequence of poses.
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.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
double sqrDistanceTo(const TPoint3D &p) const
Point-to-point distance, squared.
std::set< T > make_set(const T &v0, const T &v1)
double read_double(const std::string §ion, const std::string &name, double defaultValue, bool failIfNotFound=false) const
mrpt::math::CMatrixDouble W_star
The reference covariance matrix used to compute vehicle_uncertainty.
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 ...
TGEODETICCOORDS getAsStruct() const
Return the geodetic coords as a mrpt::topography::TGeodeticCoords structure (requires linking against...
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...
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
std::shared_ptr< CObservationGPS > Ptr
content_t fields
Message content, accesible by individual fields.
Declares a class that represents a Probability Density function (PDF) of a 3D pose ...
This class stores a time-stamped trajectory in SE(3) (CPose3D poses).
TEntryType getType(size_t index) const
Returns the type of a given element.
void changeCoordinatesReference(const CPose3D &newReferenceBase) override
this = p (+) this.
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...
This namespace provides topography helper functions, coordinate transformations.
This class stores messages from GNSS or GNSS+IMU devices, from consumer-grade inexpensive GPS receive...
T z() const
Return z coordinate of the quaternion.
size_t size() const
Returns the number of actions / observations object in the sequence.
std::map< mrpt::system::TTimeStamp, mrpt::math::TPoint3D > best_gps_path
the path of the "best" GPS.
A structure for holding correspondences between two sets of points or points-like entities in 2D or 3...
void getCommentTextAsConfigFile(mrpt::utils::CConfigFileMemory &memCfg) const
Saves the block of comment text for the rawlog into the passed config file object.