12 #include <mrpt/config.h> 19 #include <vtkCellArray.h> 20 #include <vtkDoubleArray.h> 21 #include <vtkPointData.h> 22 #include <vtkPoints.h> 23 #include <vtkSmartPointer.h> 24 #include <vtkStructuredGrid.h> 25 #include <vtkVersion.h> 26 #include <vtkXMLStructuredGridWriter.h> 40 double x_min,
double x_max,
double y_min,
double y_max,
double z_min,
41 double z_max,
double voxel_size,
bool call_initialize_now)
43 x_min, x_max, y_min, y_max, z_min, z_max, voxel_size ,
47 if (call_initialize_now) this->internal_initialize();
52 const double x_min,
const double x_max,
const double y_min,
53 const double y_max,
const double z_min,
const double z_max,
54 const double resolution_xy,
const double resolution_z,
60 x_min, x_max, y_min, y_max, z_min, z_max, resolution_xy, resolution_z,
62 this->internal_initialize();
68 double new_x_min,
double new_x_max,
double new_y_min,
double new_y_max,
69 double new_z_min,
double new_z_max,
71 double additionalMarginMeters)
76 new_x_min, new_x_max, new_y_min, new_y_max, new_z_min, new_z_max,
77 defaultValueNewCells, additionalMarginMeters);
78 this->internal_initialize(
false);
86 internal_initialize();
91 if (erase_prev_contents)
99 m_gmrf.setVerbosityLevel(this->getMinLoggingLevel());
100 if (erase_prev_contents)
103 m_mrf_factors_activeObs.clear();
108 m_gmrf.clearAllConstraintsByType_Binary();
110 m_mrf_factors_priors.clear();
113 const size_t nodeCount = m_map.size();
118 "[internal_initialize] Creating priors for GMRF with " 119 << nodeCount <<
" nodes." << std::endl);
123 m_mrf_factors_activeObs.resize(nodeCount);
124 m_gmrf.initialize(nodeCount);
130 size_t cx = 0, cy = 0, cz = 0;
131 for (
size_t j = 0; j < nodeCount; j++)
138 const size_t c_idx_to_check[3] = {cx, cy, cz};
139 const size_t c_idx_to_check_limits[3] = {m_size_x - 1, m_size_y - 1,
141 const size_t c_neighbor_idx_incr[3] = {1, m_size_x, m_size_x_times_y};
145 if (c_idx_to_check[
dir] >= c_idx_to_check_limits[
dir])
continue;
147 const size_t i = j + c_neighbor_idx_incr[
dir];
150 double edge_lamdba = .0;
151 if (custom_connectivity !=
nullptr)
153 const bool is_connected =
155 this, cx, cy, cz, cx + (
dir == 0 ? 1 : 0),
156 cy + (
dir == 1 ? 1 : 0), cz + (
dir == 2 ? 1 : 0),
158 if (!is_connected)
continue;
162 edge_lamdba = insertionOptions.GMRF_lambdaPrior;
168 new_prior.
Lambda = edge_lamdba;
170 m_mrf_factors_priors.push_back(new_prior);
171 m_gmrf.addConstraint(
172 *m_mrf_factors_priors.rbegin());
176 if (++cx >= m_size_x)
179 if (++cy >= m_size_y)
188 "[internal_initialize] Prior built in " << tictac.
Tac() <<
" s\n" 200 std::ostream& out)
const 203 "GMRF_lambdaPrior = %f\n", GMRF_lambdaPrior);
205 "GMRF_skip_variance = %s\n",
206 GMRF_skip_variance ?
"true" :
"false");
212 GMRF_lambdaPrior =
iniFile.read_double(
213 section.c_str(),
"GMRF_lambdaPrior", GMRF_lambdaPrior);
214 GMRF_skip_variance =
iniFile.read_bool(
215 section.c_str(),
"GMRF_skip_variance", GMRF_skip_variance);
226 vtkStructuredGrid* vtkGrid = vtkStructuredGrid::New();
227 this->getAsVtkStructuredGrid(vtkGrid);
230 vtkSmartPointer<vtkXMLStructuredGridWriter> writer =
231 vtkSmartPointer<vtkXMLStructuredGridWriter>::New();
232 writer->SetFileName(fil.c_str());
234 #if VTK_MAJOR_VERSION <= 5 235 writer->SetInput(vtkGrid);
237 writer->SetInputData(vtkGrid);
240 int ret = writer->Write();
254 std::ofstream f_mean, f_stddev;
256 f_mean.open(filName_mean);
257 if (!f_mean.is_open())
263 f_mean <<
"x coord, y coord, z coord, scalar\n";
266 if (!filName_stddev.empty())
268 f_stddev.open(filName_stddev);
269 if (!f_stddev.is_open())
275 f_mean <<
"x coord, y coord, z coord, scalar\n";
279 const size_t nodeCount = m_map.size();
280 size_t cx = 0, cy = 0, cz = 0;
281 for (
size_t j = 0; j < nodeCount; j++)
283 const double x = idx2x(cx),
y = idx2y(cy),
z = idx2z(cz);
284 const double mean_val = m_map[j].mean_value;
285 const double stddev_val = m_map[j].stddev_value;
289 if (f_stddev.is_open())
293 if (++cx >= m_size_x)
296 if (++cy >= m_size_y)
310 !m_mrf_factors_activeObs.empty(),
311 "Cannot update a map with no observations!");
314 m_gmrf.updateEstimation(
315 x_incr, insertionOptions.GMRF_skip_variance ?
nullptr : &x_var);
317 ASSERT_(
size_t(m_map.size()) ==
size_t(x_incr.size()));
319 insertionOptions.GMRF_skip_variance ||
320 size_t(m_map.size()) ==
size_t(x_var.size()));
323 for (
size_t j = 0; j < m_map.size(); j++)
325 m_map[j].mean_value += x_incr[j];
326 m_map[j].stddev_value =
327 insertionOptions.GMRF_skip_variance ? .0 : std::sqrt(x_var[j]);
334 m_gmrf_connectivity = new_connectivity_descriptor;
339 const double sensorReading,
341 const double sensorVariance,
349 const bool update_map)
355 m_mrf_factors_activeObs.size() == m_map.size(),
356 "Trying to insert observation in uninitialized map (!)");
358 const size_t cell_idx =
359 cellAbsIndexFromCXCYCZ(x2idx(point.
x), y2idx(point.
y), z2idx(point.
z));
360 if (cell_idx == INVALID_VOXEL_IDX)
return false;
365 new_obs.
Lambda = 1.0 / sensorVariance;
367 m_mrf_factors_activeObs[cell_idx].push_back(new_obs);
368 m_gmrf.addConstraint(
369 *m_mrf_factors_activeObs[cell_idx].rbegin());
371 if (update_map) this->updateMapEstimation();
382 dyngridcommon_writeToStream(out);
393 #if MRPT_IS_BIG_ENDIAN 395 out << m_map[i].mean_value << m_map[i].stddev_value;
398 out.
WriteBuffer(&m_map[0],
sizeof(m_map[0]) * m_map.size());
401 out << insertionOptions.GMRF_lambdaPrior
402 << insertionOptions.GMRF_skip_variance;
412 dyngridcommon_readFromStream(
in);
424 #if MRPT_IS_BIG_ENDIAN 426 in >> m_map[i].mean_value >> m_map[i].stddev_value;
429 in.ReadBuffer(&m_map[0],
sizeof(m_map[0]) * m_map.size());
431 in >> insertionOptions.GMRF_lambdaPrior >>
432 insertionOptions.GMRF_skip_variance;
441 vtkStructuredGrid* output,
const std::string& label_mean,
447 const size_t nx = this->getSizeX(),
ny = this->getSizeY(),
448 nz = this->getSizeZ();
450 const int num_values =
nx *
ny *
nz;
452 vtkPoints* newPoints = vtkPoints::New();
454 vtkDoubleArray* newData = vtkDoubleArray::New();
455 newData->SetNumberOfComponents(3);
456 newData->SetNumberOfTuples(num_values);
458 vtkDoubleArray* mean_arr = vtkDoubleArray::New();
459 mean_arr->SetNumberOfComponents(1);
460 mean_arr->SetNumberOfTuples(num_values);
462 vtkDoubleArray* std_arr = vtkDoubleArray::New();
463 std_arr->SetNumberOfComponents(1);
464 std_arr->SetNumberOfTuples(num_values);
466 vtkIdType numtuples = newData->GetNumberOfTuples();
469 size_t cx = 0, cy = 0, cz = 0;
470 for (vtkIdType cc = 0; cc < numtuples; cc++)
472 const double x = idx2x(cx),
y = idx2y(cy),
z = idx2z(cz);
474 newData->SetComponent(cc, 0,
x);
475 newData->SetComponent(cc, 1,
y);
476 newData->SetComponent(cc, 2,
z);
478 mean_arr->SetComponent(cc, 0, m_map[cc].mean_value);
479 std_arr->SetComponent(cc, 0, m_map[cc].stddev_value);
482 if (++cx >= m_size_x)
485 if (++cy >= m_size_y)
492 ASSERT_(
size_t(m_map.size()) ==
size_t(numtuples));
495 newPoints->SetData(newData);
498 output->SetExtent(0,
nx - 1, 0,
ny - 1, 0,
nz - 1);
499 output->SetPoints(newPoints);
502 mean_arr->SetName(label_mean.c_str());
503 std_arr->SetName(label_stddev.c_str());
504 output->GetPointData()->AddArray(mean_arr);
505 output->GetPointData()->AddArray(std_arr);
519 return m_parent->m_map[this->node_id].mean_value - this->obsValue;
532 return m_parent->m_map[this->node_id_i].mean_value -
533 m_parent->m_map[this->node_id_j].mean_value;
540 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.
double x
X,Y,Z coordinates.
virtual void clear()
Erase the contents of all the cells, setting them to their default values (default ctor)...
#define THROW_EXCEPTION(msg)
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.
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
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.
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 &defaultValueNewCells, double additionalMarginMeters=2)
Changes the size of the grid, maintaining previous contents.
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);
GLsizei const GLchar ** string
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...
GLfloat GLfloat GLfloat GLfloat nx
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
#define ASSERT_ABOVE_(__A, __B)
TVoxelInterpolationMethod
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.
bool saveAsVtkStructuredGrid(const std::string &fil) const
Save the current estimated grid to a VTK file (.vts) as a "structured grid".
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.
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.
unsigned __int32 uint32_t
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...