/******************************************************************************
*
* Slamcore Confidential
* ---------------------
*
* Slamcore Limited
* All Rights Reserved.
* (C) Copyright 2021
*
* NOTICE:
*
* All information contained herein is, and remains the property of Slamcore
* Limited and its suppliers, if any. The intellectual and technical concepts
* contained herein are proprietary to Slamcore Limited and its suppliers and
* may be covered by patents in process, and are protected by trade secret or
* copyright law. Dissemination of this information or reproduction of this
* material is strictly forbidden unless prior written permission is obtained
* from Slamcore Limited.
*
******************************************************************************/
/**
* @file
* @ingroup slamcore_sdk_examples
* @brief API example to set up and run a SLAM system in multisession mode.
*
* This demonstrates how to perform SLAM with an already saved session file
* from another execution of the software.
*/
#include "slamcore/objects/meta_data.hpp"
#include "slamcore/slam/slam_create.hpp"
#include "slamcore/types/tracking_status.hpp"
#include <ctime>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <system_error>
namespace
{
/**
* Logging callback.
*
* @param message Message received by the logging system.
*/
void logInfo(const slamcore::LogMessageInterface& message)
{
const time_t time = slamcore::host_clock::to_time_t(message.getTimestamp());
struct tm tm;
localtime_r(&time, &tm);
std::cerr << "[" << message.getSeverity() << " " << std::put_time(&tm, "%FT%T%z") << "] "
<< message.getMessage() << "\n";
}
} // namespace
// Convenience struct to store Pose data.
struct Pose
{
struct Translation
{
double x{0}, y{0}, z{0};
} position;
struct Rotation
{
double x{0}, y{0}, z{0}, w{1};
} orientation;
};
// Convenience struct to store Metadata information.
struct MetaData
{
slamcore::TrackingStatus trackingStatus{slamcore::TrackingStatus::NOT_INITIALISED};
int64_t numFeatures{0}, trackedFeatures{0};
};
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "Usage: " << argv[0] << " <session-file>" << '\n';
return -1;
}
// Initialise Slamcore API
slamcore::slamcoreInit(slamcore::LogSeverity::Info, ::logInfo);
// Create/Connect SLAM System
slamcore::v0::SystemConfiguration sysCfg;
sysCfg.LoadSessionFilePath = argv[1];
std::unique_ptr<slamcore::SLAMSystemCallbackInterface> slam = slamcore::createSLAMSystem(sysCfg);
if (!slam)
{
std::cerr << "Error creating SLAM system!" << '\n';
slamcore::slamcoreDeinit();
return -1;
}
std::cout << "Starting SLAM..." << '\n';
// Open the device
slam->open();
// Enable streams
slam->setStreamEnabled(slamcore::Stream::Pose, true);
slam->setStreamEnabled(slamcore::Stream::MetaData, true);
slam->setStreamEnabled(slamcore::Stream::SLAMStatus, true);
// Register callbacks
Pose pose;
slam->registerCallback<slamcore::Stream::Pose>(
[&pose](const slamcore::PoseInterface<slamcore::camera_clock>::CPtr& poseObj)
{
pose.position.x = poseObj->getTranslation().x();
pose.position.y = poseObj->getTranslation().y();
pose.position.z = poseObj->getTranslation().z();
pose.orientation.x = poseObj->getRotation().x();
pose.orientation.y = poseObj->getRotation().y();
pose.orientation.z = poseObj->getRotation().z();
pose.orientation.w = poseObj->getRotation().w();
});
MetaData meta;
slam->registerCallback<slamcore::Stream::MetaData>(
[&meta](const slamcore::MetaDataInterface::CPtr& metaObj)
{
switch (metaObj->getID())
{
case slamcore::MetaDataID::NumFeatures:
{
metaObj->getValue(meta.numFeatures);
break;
}
case slamcore::MetaDataID::TrackedFeatures:
{
metaObj->getValue(meta.trackedFeatures);
break;
}
default:
{
}
}
});
slam->registerCallback<slamcore::Stream::SLAMStatus>(
[&meta](const slamcore::SLAMStatusInterface::CPtr& slamStatus)
{ meta.trackingStatus = slamStatus->getTrackingStatus(); });
// Start streaming
slam->start();
// Main receiving loop
while (slam->spin())
{
std::cout << "Tracking Status: " << meta.trackingStatus << '\n';
std::cout << "Tracked Features: " << meta.trackedFeatures << "/" << meta.numFeatures << '\n';
if (meta.trackingStatus == slamcore::TrackingStatus::OK)
{
std::cout << "Position : " << pose.position.x << ", " << pose.position.y << ", "
<< pose.position.z << '\n';
std::cout << "Orientation: " << pose.orientation.x << ", " << pose.orientation.y << ", "
<< pose.orientation.z << ", " << pose.orientation.w << '\n';
}
else
{
std::cout << "Position : ??, ??, ??" << '\n';
std::cout << "Orientation: ??, ??, ??, ??" << '\n';
}
}
// Stop SLAM
slam->stop();
// Disconnect/Close SLAM
slam->close();
// Deinitialise Slamcore API
slamcore::slamcoreDeinit();
std::cout << "We're Done Here." << '\n';
}