36 #include <Eigen/SparseCholesky>    41 using namespace Eigen;
    67         for (
size_t other = 0; other < scan - options.
loopSize; other++)
    69             if ((scans[other]->getPosition() - pos).squaredNorm() < maxDist)
    71                 output.push_back(other);
    78         auto tree = KDTree::create(cur, options.
maxLeafSize);
    81         for (
size_t other = 0; other < scan - options.
loopSize; other++)
    83             maxLen = max(maxLen, scans[other]->numPoints());
    87         for (
size_t other = 0; other < scan - options.
loopSize; other++)
    89             size_t count = KDTree::nearestNeighbors(tree, scans[other], neighbors, options.
slamMaxDistance);
    92                 output.push_back(other);
    99     return !output.empty();
   128     graph.reserve(n * n / 2);
   134     for (
size_t iteration = 0;
   147         X = SimplicialCholesky<GraphMatrix>().compute(A).solve(B);
   149         double sum_position_diff = 0.0;
   152         #pragma omp parallel for reduction(+:sum_position_diff) schedule(static)   153         for (
size_t i = 1; i <= last; i++)
   155             if (new_scans.empty() || new_scans.at(i))
   162                 Matrix4d initialPose = scan->pose();
   167                     cout << 
"Start of " << i << 
": " << pos.transpose() << 
", " << theta.transpose() << endl;
   170                 double ctx, stx, cty, sty;
   173                 sincos(theta.x(), &stx, &ctx);
   174                 sincos(theta.y(), &sty, &cty);
   176                 __sincos(theta.x(), &stx, &ctx);
   177                 __sincos(theta.y(), &sty, &cty);
   181                 Ha(0, 4) = -pos.z() * ctx + pos.y() * stx;
   182                 Ha(0, 5) = pos.y() * cty * ctx + pos.z() * stx * cty;
   185                 Ha(1, 4) = -pos.x() * stx;
   186                 Ha(1, 5) = -pos.x() * ctx * cty + pos.z() * sty;
   190                 Ha(2, 4) = pos.x() * ctx;
   191                 Ha(2, 5) = -pos.x() * cty * stx - pos.y() * sty;
   196                 Ha(4, 5) = ctx * cty;
   199                 Ha(5, 5) = -stx * cty;
   202                 Vector6d result = Ha.inverse() * X.block<6, 1>((i - 1) * 6, 0);
   205                 pos -= result.block<3, 1>(0, 0);
   206                 theta -= result.block<3, 1>(3, 0);
   212                     cout << 
"End: pos: " << pos.transpose() << 
"," << endl << 
"theta: " << theta.transpose() << endl;
   215                 transform = transform * initialPose.inverse();
   219                 sum_position_diff += result.block<3, 1>(0, 0).
norm();
   227             for (
size_t i = last + 1; i < scans.size(); i++)
   233         cout << 
"Sum of Position differences = " << sum_position_diff << endl;
   235         double avg = sum_position_diff / n;
   236         if (avg < m_options->slamEpsilon)
   247     for (
size_t i = 1; i <= last; i++)
   249         graph.push_back(make_pair(i - 1, i));
   252     vector<size_t> others;
   257         for (
size_t other : others)
   259             graph.push_back(make_pair(other, i));
   269     map<size_t, KDTreePtr> trees;
   270     for (
size_t i = 0; i < graph.size(); i++)
   272         size_t a = graph[i].first;
   273         if (trees.find(a) == trees.end())
   276             trees.insert(make_pair(a, tree));
   280     vector<pair<Matrix6d, Vector6d>> coeff(graph.size());
   282     #pragma omp parallel for schedule(dynamic)   283     for (
size_t i = 0; i < graph.size(); i++)
   286         std::tie(a, b) = graph[i];
   295         coeff[i] = make_pair(coeffMat, coeffVec);
   300     map<pair<int, int>, 
Matrix6d> result;
   305     for (
size_t i = 0; i < graph.size(); i++)
   308         std::tie(a, b) = graph[i];
   312         std::tie(coeffMat, coeffVec) = coeff[i];
   316         int offsetA = (a - 1) * 6;
   317         int offsetB = (b - 1) * 6;
   321             vec.block<6, 1>(offsetA, 0) += coeffVec;
   322             auto key = make_pair(offsetA, offsetA);
   323             auto found = result.find(key);
   324             if (found == result.end())
   326                 result.insert(make_pair(key, coeffMat));
   330                 found->second += coeffMat;
   335             vec.block<6, 1>(offsetB, 0) -= coeffVec;
   336             auto key = make_pair(offsetB, offsetB);
   337             auto found = result.find(key);
   338             if (found == result.end())
   340                 result.insert(make_pair(key, coeffMat));
   344                 found->second += coeffMat;
   347         if (offsetA >= 0 && offsetB >= 0)
   349             auto key = make_pair(offsetA, offsetB);
   350             auto found = result.find(key);
   351             if (found == result.end())
   353                 result.insert(make_pair(key, -coeffMat));
   357                 found->second -= coeffMat;
   360             key = make_pair(offsetB, offsetA);
   361             found = result.find(key);
   362             if (found == result.end())
   364                 result.insert(make_pair(key, -coeffMat));
   368                 found->second -= coeffMat;
   373     vector<Triplet<double>> triplets;
   374     triplets.reserve(result.size() * 6 * 6);
   377     for (
auto& e : result)
   381         for (
int dx = 0; dx < 6; dx++)
   383             for (
int dy = 0; dy < 6; dy++)
   385                 triplets.push_back(Triplet<double>(x + dx, y + dy, m(dx, dy)));
   389     mat.setFromTriplets(triplets.begin(), triplets.end());
   394     size_t n = scan->numPoints();
   402     double xy, yz, xz, ypz, xpz, xpy;
   403     xy = yz = xz = ypz = xpz = xpy = 0.0;
   405     for (
size_t i = 0; i < n; i++)
   407         if (results[i] == 
nullptr)
   412         Vector3d p = scan->point(i).cast<
double>();
   413         Vector3d r = results[i]->cast<
double>();
   418         double x = mid.x(), y = mid.y(), z = mid.z();
   422         xpy += x * x + y * y;
   423         xpz += x * x + z * z;
   424         ypz += y * y + z * z;
   430         mz.block<3, 1>(0, 0) += d;
   432         mz(3) += -z * d.y() + y * d.z();
   433         mz(4) += -y * d.x() + x * d.y();
   434         mz(5) += z * d.x() - x * d.z();
   438     mm(0, 0) = mm(1, 1) = mm(2, 2) = pairs;
   443     mm(0, 4) = mm(4, 0) = -sum.y();
   444     mm(0, 5) = mm(5, 0) = sum.z();
   445     mm(1, 3) = mm(3, 1) = -sum.z();
   446     mm(1, 4) = mm(4, 1) = sum.x();
   447     mm(2, 3) = mm(3, 2) = sum.y();
   448     mm(2, 5) = mm(5, 2) = -sum.x();
   450     mm(3, 4) = mm(4, 3) = -xz;
   451     mm(3, 5) = mm(5, 3) = -xy;
   452     mm(4, 5) = mm(5, 4) = -yz;
   458     for (
size_t i = 0; i < n; i++)
   460         if (results[i] == 
nullptr)
   465         Vector3d p = scan->point(i).cast<
double>();
   466         Vector3d r = results[i]->cast<
double>();
   471         ss += pow(delta.x() + (d(0) - mid.y() * d(4) + mid.z() * d(5)), 2.0)
   472               + pow(delta.y() + (d(1) - mid.z() * d(3) + mid.x() * d(4)), 2.0)
   473               + pow(delta.z() + (d(2) + mid.y() * d(3) - mid.x() * d(5)), 2.0);
   478     ss = ss / (2.0 * pairs - 3.0);
   490     double sx = sin(theta[0]);
   491     double cx = cos(theta[0]);
   492     double sy = sin(theta[1]);
   493     double cy = cos(theta[1]);
   494     double sz = sin(theta[2]);
   495     double cz = cos(theta[2]);
   499         -cx* sy* cz + sx* sz,
   502         -sx* sy* sz + cx* cz,
   516     mat.transposeInPlace();
   523     Matrix4d mat = inputMat.transpose();
   528     rPosTheta[1] = asin(max(-1.0, min(1.0, mat(2, 0)))); 
   529     if (mat(0, 0) <= 0.0)
   531         rPosTheta[1] = 
M_PI - rPosTheta[1];
   534     double C = cos(rPosTheta[1]);
   535     if (fabs( C ) > 0.005)                    
   537         _trX      =  mat(2, 2) / C;             
   538         _trY      =  -mat(2, 1) / C;
   539         rPosTheta[0]  = atan2( _trY, _trX );
   540         _trX      =  mat(0, 0) / C;              
   541         _trY      = -mat(1, 0) / C;
   542         rPosTheta[2]  = atan2( _trY, _trX );
   549         rPosTheta[2]  = atan2( _trY, _trX );
   552     rPos = inputMat.block<3, 1>(0, 3);
 void doGraphSLAM(const std::vector< SLAMScanPtr > &scans, size_t last, const std::vector< bool > &new_scans=std::vector< bool >()) const
runs the GraphSLAM algorithm 
std::vector< std::pair< int, int > > Graph
void fillEquation(const std::vector< SLAMScanPtr > &scans, const Graph &graph, GraphMatrix &mat, GraphVector &vec) const
A function to fill the linear system mat * x = vec. 
const kaboom::Options * options
The Scan was part of a GraphSLAM Iteration. 
bool createFrames
Keep track of all previous Transformations of Scans for Animation purposes like 'show' from slam6D...
static size_t nearestNeighbors(KDTreePtr tree, SLAMScanPtr scan, Neighbor *neighbors, double maxDistance, Vector3d ¢roid_m, Vector3d ¢roid_d)
Finds the nearest neighbors of all points in a Scan using a pre-generated KDTree. ...
void Matrix4ToEuler(const Matrix4d mat, Vector3d &rPosTheta, Vector3d &rPos)
Conversion from Matrix to Pose representation. 
void eulerCovariance(KDTreePtr tree, SLAMScanPtr scan, Matrix6d &outMat, Vector6d &outVec) const
Eigen::VectorXd GraphVector
bool findCloseScans(const std::vector< SLAMScanPtr > &scans, size_t scan, const SLAMOptions &options, std::vector< size_t > &output)
finds Scans that are "close" to a Scan as determined by a Loopclosing strategy 
void createGraph(const std::vector< SLAMScanPtr > &scans, size_t last, Graph &graph) const
Creates a graph. An edge between nodes(scans) means posible overlap. 
Eigen::Vector3d Vector3d
Eigen 3D vector, double precision. 
A struct to configure SLAMAlign. 
The Scan has not been registered yet. 
bool verbose
Show more detailed output. Useful for fine-tuning Parameters or debugging. 
void EulerToMatrix4(const Vector3d &pos, const Vector3d &theta, Matrix4d &mat)
Conversion from Pose to Matrix representation. 
int slamIterations
Number of ICP iterations during Loopclosing and number of GraphSLAM iterations. 
std::shared_ptr< KDTree > KDTreePtr
static std::shared_ptr< KDTree > create(SLAMScanPtr scan, int maxLeafSize=20)
Creates a new KDTree from the given Scan. 
bool findCloseScans(const vector< SLAMScanPtr > &scans, size_t scan, const SLAMOptions &options, vector< size_t > &output)
Lists all numbers of scans near to the scan. 
Eigen::Matrix< double, 6, 6 > Matrix6d
6D matrix double precision 
double slamMaxDistance
The maximum distance between two points during SLAM. 
Eigen::Matrix4d Matrix4d
Eigen 4x4 matrix, double precision. 
int maxLeafSize
The maximum number of Points in a Leaf of a KDTree. 
Eigen::Matrix< double, 6, 1 > Vector6d
6D vector double precision 
std::shared_ptr< SLAMScanWrapper > SLAMScanPtr
Eigen::SparseMatrix< double > GraphMatrix
__kf_device__ float norm(const float3 &v)
const SLAMOptions * m_options
PointBufferPtr transform(PointBufferPtr pc_in, const Transformd &T)