Program Listing for File openvslam_api.cpp¶
↰ Return to documentation for file (lib_openvslam/openvslam_api.cpp
)
// To prevent linker language error
#include <queue>
#include <iostream>
#ifdef RUN_SLAM
#include "openvslam_api.hpp"
#include "pangolin_viewer/viewer.h"
#include "openvslam/system.h"
#include "openvslam/config.h"
#include "openvslam/util/stereo_rectifier.h"
#include <spdlog/spdlog.h>
class OpenVSLAM_API::impl{
public:
impl(bool& run,
const std::string config_file_path,
const std::string vocab_file_path,
const std::string load_map_db_path,
const std::string save_map_db_path,
const std::string mask_img_path,
bool load_map,
bool continue_mapping,
float scale
);
void addFrameToQueue(cv::Mat new_frame);
void startMonoThread();
void mono_tracking(const std::shared_ptr<openvslam::config>& cfg);
private:
std::queue<cv::Mat> frame_queue;
std::mutex frame_m;
std::thread mono_thread;
bool& run_;
const std::string config_file_path_;
const std::string vocab_file_path_;
const std::string load_map_db_path_;
const std::string save_map_db_path_;
const std::string mask_img_path_;
bool load_map_ = false, continue_mapping_ = true;
float scale_ = 1;
};
OpenVSLAM_API::impl::impl(
bool& run,
const std::string config_file_path,
const std::string vocab_file_path,
const std::string load_map_db_path,
const std::string save_map_db_path,
const std::string mask_img_path,
bool load_map,
bool continue_mapping,
float scale
)
:
run_(run),
config_file_path_(config_file_path),
vocab_file_path_(vocab_file_path),
load_map_db_path_(load_map_db_path),
save_map_db_path_(save_map_db_path),
mask_img_path_(mask_img_path),
load_map_(load_map),
continue_mapping_(continue_mapping),
scale_(scale)
{
if(load_map_ && !load_map_db_path.empty()){
bool exists = false;
if (FILE *file = fopen(load_map_db_path.c_str(), "r")) {
fclose(file);
exists = true;
}
if(!exists){
load_map_ = false;
std::cout << "Map file provided does not exist" << std::endl;
}
}
}
OpenVSLAM_API::OpenVSLAM_API(bool& run,
const std::string config_file_path,
const std::string vocab_file_path,
const std::string load_map_db_path,
const std::string save_map_db_path,
const std::string mask_img_path,
bool load_map,
bool continue_mapping,
float scale){
openvslam_impl = std::make_unique<impl>(run, config_file_path, vocab_file_path,
load_map_db_path, save_map_db_path, mask_img_path, load_map, continue_mapping,
scale);
}
OpenVSLAM_API::~OpenVSLAM_API(){};
std::mutex& OpenVSLAM_API::getMutex(){
return pangolin_viewer::frame_display_sync;
}
void OpenVSLAM_API::impl::addFrameToQueue(cv::Mat new_frame){
if(frame_queue.size() < 3){
std::unique_lock<std::mutex> lk(frame_m);
frame_queue.push(new_frame.clone());
}
}
void OpenVSLAM_API::addFrameToQueue(cv::Mat new_frame){
openvslam_impl->addFrameToQueue(new_frame);
}
void OpenVSLAM_API::impl::mono_tracking(
const std::shared_ptr<openvslam::config>& cfg
){
// load the mask image
const cv::Mat mask = mask_img_path_.empty() ? cv::Mat{} : cv::imread(mask_img_path_, cv::IMREAD_GRAYSCALE);
// build a SLAM system
openvslam::system SLAM(cfg, vocab_file_path_);
if(load_map_){
SLAM.load_map_database(load_map_db_path_);
// startup the SLAM process (it does not need initialization of a map)
SLAM.startup(false);
// select to activate the mapping module or not
if (continue_mapping_) {
SLAM.enable_mapping_module();
}
else {
SLAM.disable_mapping_module();
}
}
else{
// startup the SLAM process
SLAM.startup();
}
pangolin_viewer::viewer viewer(cfg, &SLAM, SLAM.get_frame_publisher(), SLAM.get_map_publisher());
cv::Mat frame;
double timestamp = 0.0;
std::vector<double> track_times;
unsigned int num_frame = 0;
// run the SLAM in another thread
std::thread slam_thread([&]() {
while(run_){
if (SLAM.terminate_is_requested()) {
break;
}
if(frame_queue.empty()){
usleep(1000000.0 / cfg->camera_->fps_);
continue;
}
{
std::unique_lock<std::mutex> lk(frame_m);
frame = frame_queue.front();
frame_queue.pop();
}
if (frame.empty()) {
continue;
}
const auto tp_1 = std::chrono::steady_clock::now();
auto m = SLAM.feed_monocular_frame(frame, timestamp, mask);
const auto tp_2 = std::chrono::steady_clock::now();
const auto track_time = std::chrono::duration_cast<std::chrono::duration<double>>(tp_2 - tp_1).count();
track_times.push_back(track_time);
timestamp += 1.0 / cfg->camera_->fps_;
++num_frame;
}
spdlog::info( "----------- Exiting the mono thread -----------");
});
std::unique_ptr<std::thread> view = std::make_unique<std::thread>([&]{
try{
spdlog::info( "----------- Viewer thread started -----------" );
viewer.run();
}
catch(...){
spdlog::info( "----------- Viewer thread crashed -----------" );
}
});
slam_thread.join();
viewer.request_terminate();
view->join();
spdlog::info( "----------- Viewer thread joined -----------" );
// shutdown the SLAM process
SLAM.shutdown();
if (!save_map_db_path_.empty()) {
// output the map database
SLAM.save_map_database(save_map_db_path_);
}
// spdlog::info( "SLAM shutdown" );
}
void OpenVSLAM_API::impl::startMonoThread(){
mono_thread = std::thread([&]{
try{
spdlog::info( "----------- Mono thread started -----------" );
std::shared_ptr<openvslam::config> cfg = std::make_shared<openvslam::config>(config_file_path_);
mono_tracking(cfg);
}
catch(...){
spdlog::info( "----------- Mono thread crashed -----------" );
spdlog::info( "Please check whether the config.yaml file is in the build directory" );
spdlog::info( "Please check whether the ORB vocabulary is in the build directory" );
}
});
mono_thread.detach();
}
void OpenVSLAM_API::startMonoThread(){
openvslam_impl->startMonoThread();
}
#endif