17 #include <mrpt/config.h>
20 #include <vtkStructuredGrid.h>
21 #include <vtkDoubleArray.h>
22 #include <vtkPointData.h>
23 #include <vtkVersion.h>
24 #include <vtkCellArray.h>
25 #include <vtkPoints.h>
26 #include <vtkXMLStructuredGridWriter.h>
27 #include <vtkSmartPointer.h>
41 double x_min,
double x_max,
double y_min,
double y_max,
double z_min,
42 double z_max,
double voxel_size,
bool call_initialize_now)
44 x_min, x_max, y_min, y_max, z_min, z_max, voxel_size ,
48 if (call_initialize_now) this->internal_initialize();
53 const double x_min,
const double x_max,
const double y_min,
54 const double y_max,
const double z_min,
const double z_max,
55 const double resolution_xy,
const double resolution_z,
61 x_min, x_max, y_min, y_max, z_min, z_max, resolution_xy, resolution_z,
63 this->internal_initialize();
69 double new_x_min,
double new_x_max,
double new_y_min,
double new_y_max,
70 double new_z_min,
double new_z_max,
72 double additionalMarginMeters)
77 new_x_min, new_x_max, new_y_min, new_y_max, new_z_min, new_z_max,
78 defaultValueNewCells, additionalMarginMeters);
79 this->internal_initialize(
false);
87 internal_initialize();
92 if (erase_prev_contents)
100 m_gmrf.setVerbosityLevel(this->getMinLoggingLevel());
101 if (erase_prev_contents)
104 m_mrf_factors_activeObs.clear();
109 m_gmrf.clearAllConstraintsByType_Binary();
111 m_mrf_factors_priors.clear();
114 const size_t nodeCount = m_map.size();
119 "[internal_initialize] Creating priors for GMRF with "
120 << nodeCount <<
" nodes." << std::endl);
124 m_mrf_factors_activeObs.resize(nodeCount);
125 m_gmrf.initialize(nodeCount);
131 size_t cx = 0, cy = 0, cz = 0;
132 for (
size_t j = 0; j < nodeCount; j++)
139 const size_t c_idx_to_check[3] = {cx, cy, cz};
140 const size_t c_idx_to_check_limits[3] = {m_size_x - 1, m_size_y - 1,
142 const size_t c_neighbor_idx_incr[3] = {1, m_size_x, m_size_x_times_y};
144 for (
int dir = 0; dir < 3; dir++)
146 if (c_idx_to_check[dir] >= c_idx_to_check_limits[dir])
continue;
148 const size_t i = j + c_neighbor_idx_incr[dir];
151 double edge_lamdba = .0;
152 if (custom_connectivity !=
nullptr)
154 const bool is_connected =
156 this, cx, cy, cz, cx + (dir == 0 ? 1 : 0),
157 cy + (dir == 1 ? 1 : 0), cz + (dir == 2 ? 1 : 0),
159 if (!is_connected)
continue;
163 edge_lamdba = insertionOptions.GMRF_lambdaPrior;
169 new_prior.
Lambda = edge_lamdba;
171 m_mrf_factors_priors.push_back(new_prior);
172 m_gmrf.addConstraint(
173 *m_mrf_factors_priors.rbegin());
177 if (++cx >= m_size_x)
180 if (++cy >= m_size_y)
189 "[internal_initialize] Prior built in " << tictac.
Tac() <<
" s\n"
197 : GMRF_lambdaPrior(0.01f),
199 GMRF_skip_variance(false)
206 out.
printf(
"GMRF_lambdaPrior = %f\n", GMRF_lambdaPrior);
208 "GMRF_skip_variance = %s\n",
209 GMRF_skip_variance ?
"true" :
"false");
216 section.c_str(),
"GMRF_lambdaPrior", GMRF_lambdaPrior);
218 section.c_str(),
"GMRF_skip_variance", GMRF_skip_variance);
229 vtkStructuredGrid* vtkGrid = vtkStructuredGrid::New();
233 vtkSmartPointer<vtkXMLStructuredGridWriter> writer =
234 vtkSmartPointer<vtkXMLStructuredGridWriter>::New();
235 writer->SetFileName(fil.c_str());
237 #if VTK_MAJOR_VERSION <= 5
238 writer->SetInput(vtkGrid);
240 writer->SetInputData(vtkGrid);
243 int ret = writer->Write();
259 if (!f_mean.
open(filName_mean))
265 f_mean.
printf(
"x coord, y coord, z coord, scalar\n");
268 if (!filName_stddev.empty())
270 if (!f_stddev.
open(filName_stddev))
276 f_mean.
printf(
"x coord, y coord, z coord, scalar\n");
280 const size_t nodeCount =
m_map.size();
281 size_t cx = 0, cy = 0, cz = 0;
282 for (
size_t j = 0; j < nodeCount; j++)
285 const double mean_val =
m_map[j].mean_value;
286 const double stddev_val =
m_map[j].stddev_value;
288 f_mean.
printf(
"%f, %f, %f, %e\n",
x,
y,
z, mean_val);
291 f_stddev.
printf(
"%f, %f, %f, %e\n",
x,
y,
z, stddev_val);
312 "Cannot update a map with no observations!");
314 Eigen::VectorXd x_incr, x_var;
321 size_t(
m_map.size()) ==
size_t(x_var.size()));
324 for (
size_t j = 0; j <
m_map.size(); j++)
326 m_map[j].mean_value += x_incr[j];
327 m_map[j].stddev_value =
340 const double sensorReading,
342 const double sensorVariance,
350 const bool update_map)
357 "Trying to insert observation in uninitialized map (!)");
359 const size_t cell_idx =
366 new_obs.
Lambda = 1.0 / sensorVariance;
397 #if MRPT_IS_BIG_ENDIAN
400 out <<
m_map[i].mean_value <<
m_map[i].stddev_value;
431 #if MRPT_IS_BIG_ENDIAN
448 vtkStructuredGrid* output,
const std::string& label_mean,
457 const int num_values =
nx *
ny *
nz;
459 vtkPoints* newPoints = vtkPoints::New();
461 vtkDoubleArray* newData = vtkDoubleArray::New();
462 newData->SetNumberOfComponents(3);
463 newData->SetNumberOfTuples(num_values);
465 vtkDoubleArray* mean_arr = vtkDoubleArray::New();
466 mean_arr->SetNumberOfComponents(1);
467 mean_arr->SetNumberOfTuples(num_values);
469 vtkDoubleArray* std_arr = vtkDoubleArray::New();
470 std_arr->SetNumberOfComponents(1);
471 std_arr->SetNumberOfTuples(num_values);
473 vtkIdType numtuples = newData->GetNumberOfTuples();
476 size_t cx = 0, cy = 0, cz = 0;
477 for (vtkIdType cc = 0; cc < numtuples; cc++)
481 newData->SetComponent(cc, 0,
x);
482 newData->SetComponent(cc, 1,
y);
483 newData->SetComponent(cc, 2,
z);
485 mean_arr->SetComponent(cc, 0,
m_map[cc].mean_value);
486 std_arr->SetComponent(cc, 0,
m_map[cc].stddev_value);
502 newPoints->SetData(newData);
505 output->SetExtent(0,
nx - 1, 0,
ny - 1, 0,
nz - 1);
506 output->SetPoints(newPoints);
509 mean_arr->SetName(label_mean.c_str());
510 std_arr->SetName(label_stddev.c_str());
511 output->GetPointData()->AddArray(mean_arr);
512 output->GetPointData()->AddArray(std_arr);
526 return m_parent->m_map[this->node_id].mean_value - this->obsValue;
539 return m_parent->m_map[this->node_id_i].mean_value -
540 m_parent->m_map[this->node_id_j].mean_value;
547 double& dr_dx_i,
double& dr_dx_j)
const
#define MRPT_LOG_DEBUG_STREAM(__CONTENTS)
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
void addConstraint(const UnaryFactorVirtualBase &listOfConstraints)
Insert constraints into the GMRF problem.
void updateEstimation(Eigen::VectorXd &solved_x_inc, Eigen::VectorXd *solved_variances=nullptr)
CRandomFieldGridMap3D represents a 3D regular grid where each voxel is associated one real-valued pro...
std::vector< std::deque< TObservationGMRF > > m_mrf_factors_activeObs
Vector with the active observations and their respective Information, for each map cell.
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 writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
TVoxelInterpolationMethod
TInsertionOptions insertionOptions
ConnectivityDescriptor::Ptr m_gmrf_connectivity
Empty: default.
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) override
Changes the size of the grid, erasing previous contents.If resolution_z<0, the same resolution will b...
void internal_initialize(bool erase_prev_contents=true)
Internal: called called after each change of resolution, size, etc.
void readFromStream(mrpt::utils::CStream &in, int version) override
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
void clear() override
Erases all added observations and start again with an empty gridmap.
mrpt::graphs::ScalarFactorGraph m_gmrf
bool saveAsVtkStructuredGrid(const std::string &fil) const
Save the current estimated grid to a VTK file (.vts) as a "structured grid".
virtual 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.
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...
void setVoxelsConnectivity(const ConnectivityDescriptor::Ptr &new_connectivity_descriptor)
Sets a custom object to define the connectivity between voxels.
void getAsVtkStructuredGrid(vtkStructuredGrid *output, const std::string &label_mean=std::string("mean"), const std::string &label_stddev=std::string("stddev")) const
Returns the 3D grid contents as an VTK grid.
This class allows loading and storing values and vectors of different types from a configuration text...
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
double read_double(const std::string §ion, const std::string &name, double defaultValue, bool failIfNotFound=false) const
A 3D rectangular grid of dynamic size which stores any kind of data at each voxel.
double idx2z(int cz) const
double idx2x(int cx) const
Transform a voxel index into a coordinate value of the voxel central point.
std::vector< TRandomFieldVoxel > m_map
The cells.
static const size_t INVALID_VOXEL_IDX
int z2idx(double z) const
int x2idx(double x) const
Transform a coordinate values into voxel indexes.
int y2idx(double y) const
void dyngridcommon_writeToStream(mrpt::utils::CStream &out) const
Serialization of all parameters, except the contents of each voxel (responsability of the derived cla...
size_t cellAbsIndexFromCXCYCZ(const int cx, const int cy, const int cz) const
Gets the absolute index of a voxel in the linear container m_map[] from its cx,cy,...
virtual void clear()
Erase the contents of all the cells, setting them to their default values (default ctor).
double idx2y(int cy) const
void dyngridcommon_readFromStream(mrpt::utils::CStream &in)
Serialization of all parameters, except the contents of each voxel (responsability of the derived cla...
This CStream derived class allow using a file as a write-only, binary stream.
bool is_open()
Returns true if the file was open without errors.
bool open(const std::string &fileName, bool append=false)
Open the given file for write.
The virtual base class which provides a unified interface for all persistent objects in MRPT.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
This class implements a high-performance stopwatch.
double Tac()
Stops the stopwatch.
void Tic()
Starts the stopwatch.
EIGEN_STRONG_INLINE void fill(const Scalar v)
EIGEN_STRONG_INLINE void setSize(size_t row, size_t col)
Changes the size of matrix, maintaining its previous content as possible and padding with zeros where...
GLfloat GLfloat GLfloat GLfloat nx
GLsizei const GLchar ** string
#define ASSERT_EQUAL_(__A, __B)
#define ASSERT_ABOVE_(__A, __B)
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define THROW_EXCEPTION(msg)
#define ASSERTMSG_(f, __ERROR_MSG)
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.
unsigned __int32 uint32_t
Base class for user-supplied objects capable of describing voxels connectivity, used to build prior f...
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,...
std::shared_ptr< ConnectivityDescriptor > Ptr
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion)
See utils::CLoadableOptions.
TInsertionOptions()
Default values loader.
bool GMRF_skip_variance
(Default:false) Skip the computation of the variance, just compute the mean
void dumpToTextStream(mrpt::utils::CStream &out) const
See utils::CLoadableOptions.
double GMRF_lambdaPrior
The information (Lambda) of fixed map constraints.
void evalJacobian(double &dr_dx) const override
Returns the derivative of the residual wrt the node value.
double obsValue
Observation value.
double evaluateResidual() const override
Return the residual/error of this observation.
double getInformation() const override
Return the inverse of the variance of this constraint.
double Lambda
"Information" of the observation (=inverse of the variance)
double Lambda
"Information" of the observation (=inverse of the variance)
double evaluateResidual() const override
Return the residual/error of this observation.
void evalJacobian(double &dr_dx_i, double &dr_dx_j) const override
Returns the derivative of the residual wrt the node values.
double getInformation() const override
Return the inverse of the variance of this constraint.
The contents of each voxel in a CRandomFieldGridMap3D map.
double x
X,Y,Z coordinates.