Program Listing for File vi-map-nabo.h¶
↰ Return to documentation for file (map-structure/vi-map/include/vi-map/vi-map-nabo.h
)
#ifndef VI_MAP_VI_MAP_NABO_H_
#define VI_MAP_VI_MAP_NABO_H_
#include <vector>
#include <Eigen/Dense>
#include <glog/logging.h>
#include <nabo/nabo.h>
#include "vi-map/vi-map.h"
namespace vi_map {
// "libnabo" wrapper for VIMap. Works for vertices or landmarks.
// See SpatialDatabase for "all within radius" queries.
// TODO(tcies) should this be consolidated with VectorizedMission?
template <typename ObjectIdType>
class VIMapNabo {
public:
explicit VIMapNabo(const VIMap& map) {
map.template getAllIds<ObjectIdType>(&id_for_index_);
initializeDatabaseFromIds(map);
}
VIMapNabo(const VIMap& map, const MissionId& mission_to_ignore) {
map.forEachMission([&](const MissionId& mission_id) {
if (mission_id != mission_to_ignore) {
std::vector<ObjectIdType> objects_in_mission;
map.template getAllIdsInMission(mission_id, &objects_in_mission);
id_for_index_.insert(
id_for_index_.end(), objects_in_mission.begin(),
objects_in_mission.end());
}
});
initializeDatabaseFromIds(map);
}
void knn(
const Eigen::Vector3d& p_G_query, const size_t k,
std::vector<ObjectIdType>* result, Eigen::VectorXd* dists2) const {
CHECK_NOTNULL(result)->resize(k);
CHECK_NOTNULL(dists2)->resize(k, 1);
CHECK(database_);
CHECK_GE(database_->cloud.cols(), k) << "Query must not exceed cloud size!";
// Nabo needs dynamic vectors.
Eigen::VectorXd query = p_G_query;
Eigen::VectorXi indices(k);
database_->knn(query, indices, *dists2, k);
for (int i = 0; i < k; ++i) {
CHECK_LT(indices(i), id_for_index_.size());
(*result)[i] = id_for_index_[indices(i)];
}
}
ObjectIdType closest(
const Eigen::Vector3d& p_G_query, double* const dist2) const {
CHECK_NOTNULL(dist2);
std::vector<ObjectIdType> result;
Eigen::VectorXd dists2;
knn(p_G_query, 1u, &result, &dists2);
*dist2 = dists2(0);
CHECK(!result.empty());
return result.front();
}
private:
void initializeDatabaseFromIds(const VIMap& map) {
CHECK(!id_for_index_.empty());
Eigen::MatrixXd database(3, id_for_index_.size());
for (int i = 0; i < id_for_index_.size(); ++i) {
database.col(i) = map.get_p_G(id_for_index_[i]);
}
database_.reset(Nabo::NNSearchD::createKDTreeLinearHeap(database));
CHECK(database_);
}
std::unique_ptr<Nabo::NNSearchD> database_;
std::vector<ObjectIdType> id_for_index_;
};
} // namespace vi_map
#endif // VI_MAP_VI_MAP_NABO_H_