12 #include <mrpt/config.h> 30 double x_min,
double x_max,
double y_min,
double y_max,
double z_min,
31 double z_max,
double voxel_size,
bool call_initialize_now)
33 x_min, x_max, y_min, y_max, z_min, z_max, voxel_size ,
37 if (call_initialize_now) this->internal_initialize();
42 const double x_min,
const double x_max,
const double y_min,
43 const double y_max,
const double z_min,
const double z_max,
44 const double resolution_xy,
const double resolution_z,
50 x_min, x_max, y_min, y_max, z_min, z_max, resolution_xy, resolution_z,
52 this->internal_initialize();
58 double new_x_min,
double new_x_max,
double new_y_min,
double new_y_max,
59 double new_z_min,
double new_z_max,
61 double additionalMarginMeters)
66 new_x_min, new_x_max, new_y_min, new_y_max, new_z_min, new_z_max,
67 defaultValueNewCells, additionalMarginMeters);
68 this->internal_initialize(
false);
76 internal_initialize();
81 if (erase_prev_contents)
89 m_gmrf.setVerbosityLevel(this->getMinLoggingLevel());
90 if (erase_prev_contents)
93 m_mrf_factors_activeObs.clear();
98 m_gmrf.clearAllConstraintsByType_Binary();
100 m_mrf_factors_priors.clear();
103 const size_t nodeCount = m_map.size();
108 "[internal_initialize] Creating priors for GMRF with " 109 << nodeCount <<
" nodes." << std::endl);
113 m_mrf_factors_activeObs.resize(nodeCount);
114 m_gmrf.initialize(nodeCount);
120 size_t cx = 0, cy = 0, cz = 0;
121 for (
size_t j = 0; j < nodeCount; j++)
128 const size_t c_idx_to_check[3] = {cx, cy, cz};
129 const size_t c_idx_to_check_limits[3] = {m_size_x - 1, m_size_y - 1,
131 const size_t c_neighbor_idx_incr[3] = {1, m_size_x, m_size_x_times_y};
135 if (c_idx_to_check[
dir] >= c_idx_to_check_limits[
dir])
continue;
137 const size_t i = j + c_neighbor_idx_incr[
dir];
140 double edge_lamdba = .0;
141 if (custom_connectivity !=
nullptr)
143 const bool is_connected =
145 this, cx, cy, cz, cx + (
dir == 0 ? 1 : 0),
146 cy + (
dir == 1 ? 1 : 0), cz + (
dir == 2 ? 1 : 0),
148 if (!is_connected)
continue;
152 edge_lamdba = insertionOptions.GMRF_lambdaPrior;
158 new_prior.
Lambda = edge_lamdba;
160 m_mrf_factors_priors.push_back(new_prior);
161 m_gmrf.addConstraint(
162 *m_mrf_factors_priors.rbegin());
166 if (++cx >= m_size_x)
169 if (++cy >= m_size_y)
178 "[internal_initialize] Prior built in " << tictac.
Tac() <<
" s\n" 190 std::ostream&
out)
const 193 "GMRF_lambdaPrior = %f\n", GMRF_lambdaPrior);
195 "GMRF_skip_variance = %s\n",
196 GMRF_skip_variance ?
"true" :
"false");
202 GMRF_lambdaPrior =
iniFile.read_double(
203 section.c_str(),
"GMRF_lambdaPrior", GMRF_lambdaPrior);
204 GMRF_skip_variance =
iniFile.read_bool(
205 section.c_str(),
"GMRF_skip_variance", GMRF_skip_variance);
209 const std::string& filName_mean,
const std::string& filName_stddev)
const 211 std::ofstream f_mean, f_stddev;
213 f_mean.open(filName_mean);
214 if (!f_mean.is_open())
220 f_mean <<
"x coord, y coord, z coord, scalar\n";
223 if (!filName_stddev.empty())
225 f_stddev.open(filName_stddev);
226 if (!f_stddev.is_open())
232 f_mean <<
"x coord, y coord, z coord, scalar\n";
236 const size_t nodeCount = m_map.size();
237 size_t cx = 0, cy = 0, cz = 0;
238 for (
size_t j = 0; j < nodeCount; j++)
240 const double x = idx2x(cx), y = idx2y(cy), z = idx2z(cz);
241 const double mean_val = m_map[j].mean_value;
242 const double stddev_val = m_map[j].stddev_value;
244 f_mean <<
mrpt::format(
"%f, %f, %f, %e\n", x, y, z, mean_val);
246 if (f_stddev.is_open())
247 f_stddev <<
mrpt::format(
"%f, %f, %f, %e\n", x, y, z, stddev_val);
250 if (++cx >= m_size_x)
253 if (++cy >= m_size_y)
267 !m_mrf_factors_activeObs.empty(),
268 "Cannot update a map with no observations!");
271 m_gmrf.updateEstimation(
272 x_incr, insertionOptions.GMRF_skip_variance ?
nullptr : &x_var);
274 ASSERT_(
size_t(m_map.size()) ==
size_t(x_incr.size()));
276 insertionOptions.GMRF_skip_variance ||
277 size_t(m_map.size()) ==
size_t(x_var.size()));
280 for (
size_t j = 0; j < m_map.size(); j++)
282 m_map[j].mean_value += x_incr[j];
283 m_map[j].stddev_value =
284 insertionOptions.GMRF_skip_variance ? .0 : std::sqrt(x_var[j]);
291 m_gmrf_connectivity = new_connectivity_descriptor;
296 const double sensorReading,
298 const double sensorVariance,
306 const bool update_map)
312 m_mrf_factors_activeObs.size() == m_map.size(),
313 "Trying to insert observation in uninitialized map (!)");
315 const size_t cell_idx =
316 cellAbsIndexFromCXCYCZ(x2idx(point.
x), y2idx(point.
y), z2idx(point.
z));
317 if (cell_idx == INVALID_VOXEL_IDX)
return false;
322 new_obs.
Lambda = 1.0 / sensorVariance;
324 m_mrf_factors_activeObs[cell_idx].push_back(new_obs);
325 m_gmrf.addConstraint(
326 *m_mrf_factors_activeObs[cell_idx].rbegin());
328 if (update_map) this->updateMapEstimation();
339 dyngridcommon_writeToStream(
out);
346 n =
static_cast<uint32_t
>(m_map.size());
350 #if MRPT_IS_BIG_ENDIAN 351 for (uint32_t i = 0; i < n; i++)
352 out << m_map[i].mean_value << m_map[i].stddev_value;
355 out.WriteBuffer(&m_map[0],
sizeof(m_map[0]) * m_map.size());
358 out << insertionOptions.GMRF_lambdaPrior
359 << insertionOptions.GMRF_skip_variance;
369 dyngridcommon_readFromStream(in);
381 #if MRPT_IS_BIG_ENDIAN 382 for (uint32_t i = 0; i < n; i++)
383 in >> m_map[i].mean_value >> m_map[i].stddev_value;
386 in.
ReadBuffer(&m_map[0],
sizeof(m_map[0]) * m_map.size());
388 in >> insertionOptions.GMRF_lambdaPrior >>
389 insertionOptions.GMRF_skip_variance;
400 return m_parent->m_map[this->node_id].mean_value - this->obsValue;
413 return m_parent->m_map[this->node_id_i].mean_value -
414 m_parent->m_map[this->node_id_j].mean_value;
421 double& dr_dx_i,
double& dr_dx_j)
const void dumpToTextStream(std::ostream &out) const override
See utils::CLoadableOptions.
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
double Tac() noexcept
Stops the stopwatch.
virtual void clear()
Erase the contents of all the cells, setting them to their default values (default ctor)...
std::string std::string format(std::string_view fmt, ARGS &&... args)
The contents of each voxel in a CRandomFieldGridMap3D map.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to all CSerializable-classes implementation files.
virtual bool getEdgeInformation(const CRandomFieldGridMap3D *parent, size_t icx, size_t icy, size_t icz, size_t jcx, size_t jcy, size_t jcz, double &out_edge_information)=0
Implement the check of whether node i=(icx,icy,icz) is connected with node j=(jcx,jcy,jcy).
void evalJacobian(double &dr_dx) const override
Returns the derivative of the residual wrt the node value.
void internal_initialize(bool erase_prev_contents=true)
Internal: called called after each change of resolution, size, etc.
A high-performance stopwatch, with typical resolution of nanoseconds.
double getInformation() const override
Return the inverse of the variance of this constraint.
double evaluateResidual() const override
Return the residual/error of this observation.
double getInformation() const override
Return the inverse of the variance of this constraint.
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
void setVoxelsConnectivity(const ConnectivityDescriptor::Ptr &new_connectivity_descriptor)
Sets a custom object to define the connectivity between voxels.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define ASSERT_(f)
Defines an assertion mechanism.
double evaluateResidual() const override
Return the residual/error of this observation.
This class allows loading and storing values and vectors of different types from a configuration text...
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
double Lambda
"Information" of the observation (=inverse of the variance)
void resize(double new_x_min, double new_x_max, double new_y_min, double new_y_max, double new_z_min, double new_z_max, const TRandomFieldVoxel &defaultValueNewvoxels, double additionalMarginMeters=2.0) override
Changes the size of the grid, maintaining previous contents.
Versatile class for consistent logging and management of output messages.
double Lambda
"Information" of the observation (=inverse of the variance)
void clear() override
Erases all added observations and start again with an empty gridmap.
string iniFile(myDataDir+string("benchmark-options.ini"))
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
#define MRPT_LOG_DEBUG_STREAM(__CONTENTS)
Use: MRPT_LOG_DEBUG_STREAM("Var=" << value << " foo=" << foo_var);
TInsertionOptions()
Default values loader.
double obsValue
Observation value.
bool saveAsCSV(const std::string &filName_mean, const std::string &filName_stddev=std::string()) const
Save the current estimated mean values to a CSV file (compatible with Paraview) with fields x y z mea...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Virtual base class for "archives": classes abstracting I/O streams.
CRandomFieldGridMap3D represents a 3D regular grid where each voxel is associated one real-valued pro...
mrpt::vision::TStereoCalibResults out
#define ASSERT_ABOVE_(__A, __B)
TVoxelInterpolationMethod
void loadFromConfigFile(const mrpt::config::CConfigFileBase &source, const std::string §ion) override
See utils::CLoadableOptions.
virtual void setSize(const double x_min, const double x_max, const double y_min, const double y_max, const double z_min, const double z_max, const double resolution_xy, const double resolution_z_=-1.0, const TRandomFieldVoxel *fill_value=nullptr)
Changes the size of the grid, ERASING all previous contents.
size_t ReadBuffer(void *Buffer, size_t Count)
Reads a block of bytes from the stream into Buffer.
bool insertIndividualReading(const double sensorReading, const double sensorVariance, const mrpt::math::TPoint3D &point, const TVoxelInterpolationMethod method, const bool update_map)
Direct update of the map with a reading in a given position of the map.
void updateMapEstimation()
Run the method-specific procedure required to ensure that the mean & variances are up-to-date with al...
void Tic() noexcept
Starts the stopwatch.
void evalJacobian(double &dr_dx_i, double &dr_dx_j) const override
Returns the derivative of the residual wrt the node values.
void setSize(const double x_min, const double x_max, const double y_min, const double y_max, const double z_min, const double z_max, const double resolution_xy, const double resolution_z=-1.0, const TRandomFieldVoxel *fill_value=nullptr) override
Changes the size of the grid, erasing previous contents.If resolution_z<0, the same resolution will b...
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
Base class for user-supplied objects capable of describing voxels connectivity, used to build prior f...