Skip to content

Commit

Permalink
WIP SpatialFeature integration
Browse files Browse the repository at this point in the history
  • Loading branch information
saching13 committed Feb 8, 2023
1 parent c27bfc0 commit e94aaba
Show file tree
Hide file tree
Showing 33 changed files with 1,824 additions and 216 deletions.
133 changes: 88 additions & 45 deletions examples/OakKimeraVIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,17 @@
#include "kimera-vio/utils/Statistics.h"
#include "kimera-vio/utils/Timer.h"

bool enableStereo = false;

DEFINE_string(
params_folder_path,
"../params/OAK-D-mod",
"Path to the folder containing the yaml files with the VIO parameters.");

DEFINE_bool(enable_ondevice_stereo_feature,
true,
"Enable Stereo and Feature tracking from On-Device");

bool enableStereoFeature = false;

dai::Pipeline createPipeline(){
dai::Pipeline pipeline;
Expand All @@ -56,71 +66,68 @@ dai::Pipeline createPipeline(){

auto xoutImu = pipeline.create<dai::node::XLinkOut>();
auto xoutL = pipeline.create<dai::node::XLinkOut>();
auto xoutR = pipeline.create<dai::node::XLinkOut>();
auto xoutRectifL = pipeline.create<dai::node::XLinkOut>();
auto xoutRectifR = pipeline.create<dai::node::XLinkOut>();

// XLinkOut
xoutImu->setStreamName("imu");
// xoutRight->setStreamName("right");
// xoutDisp->setStreamName("disparity");
// xoutDepth->setStreamName("depth");
xoutRectifL->setStreamName("rectLeft");
xoutRectifR->setStreamName("rectRight");
xoutL->setStreamName("left");
xoutR->setStreamName("right");

// Properties
monoLeft->setResolution(dai::MonoCameraProperties::SensorResolution::THE_720_P);
monoLeft->setBoardSocket(dai::CameraBoardSocket::LEFT);
monoRight->setResolution(dai::MonoCameraProperties::SensorResolution::THE_720_P);
monoRight->setBoardSocket(dai::CameraBoardSocket::RIGHT);

// stereo->setDefaultProfilePreset(dai::node::StereoDepth::PresetMode::HIGH_DENSITY); // HIGH_ACCURACY
// stereo->setRectifyEdgeFillColor(0);
// stereo->initialConfig.setMedianFilter(dai::MedianFilter::KERNEL_5x5);

// stereo->setSubpixel(true);
// stereo->setLeftRightCheck(true);
// stereo->setExtendedDisparity(false);

// stereo->enableDistortionCorrection(true);

if (enableStereo){
if (enableStereoFeature){
auto stereo = pipeline.create<dai::node::StereoDepth>();
// stereo->syncedLeft.link(xoutLeft->input);
// stereo->syncedRight.link(xoutRight->input);
// stereo->disparity.link(xoutDisp->input);
// Stereo Config
stereo->setDefaultProfilePreset(dai::node::StereoDepth::PresetMode::HIGH_ACCURACY);
stereo->initialConfig.setMedianFilter(dai::MedianFilter::KERNEL_5x5);
stereo->setLeftRightCheck(true);
stereo->setExtendedDisparity(false);
stereo->setSubpixel(true);
stereo->setDepthAlign(dai::CameraBoardSocket::LEFT)

// Linking
auto xoutDepth = pipeline.create<dai::node::XLinkOut>();
xoutDepth->setStreamName("depth");

stereo->depth.link(xoutDepth->input);
monoLeft->out.link(stereo->left);
monoRight->out.link(stereo->right);

stereo->setRectification(false);
// if(outputRectified) {
stereo->syncedLeft.link(xoutL->input);
stereo->syncedRight.link(xoutR->input);
stereo->rectifiedLeft.link(xoutRectifL->input);
stereo->rectifiedRight.link(xoutRectifR->input);

stereo->syncedLeft.link(xoutL->input);

// Feature Tracker setup
auto featureTrackerRight = pipeline.create<dai::node::FeatureTracker>();
monoLeft->out.link(featureTrackerRight->inputImage);

auto numShaves = 2;
auto numMemorySlices = 2;
featureTrackerRight->setHardwareResources(numShaves, numMemorySlices);

// COnfig Optical FLow
auto featureTrackerConfig = dai::FeatureTrackerConfig();
featureTrackerConfig.setOpticalFlow();
// TODO(Saching): Use FULL control of Corner Detector in future for experimentation
featureTrackerConfig.setCornerDetector(dai::FeatureTrackerConfig::CornerDetector::HARRIS);
featureTrackerConfig.setFeatureMaintainer(true);
featureTrackerRight->initialConfig = featureTrackerConfig;

auto xoutTrackedFeaturesR = pipeline.create<dai::node::XLinkOut>();
xoutTrackedFeaturesR->setStreamName("trackers");
featureTrackerRight->outputFeatures.link(xoutTrackedFeaturesR->input);
}
else{
auto xoutR = pipeline.create<dai::node::XLinkOut>();
xoutR->setStreamName("right");
monoLeft->out.link(xoutL->input);
monoRight->out.link(xoutR->input);
}

imu->out.link(xoutImu->input);

// if(outputDepth) {
// stereo->depth.link(xoutDepth->input);
// }
return pipeline;
imu->out.link(xoutImu->input);
return pipeline;
}

DEFINE_string(
params_folder_path,
"../params/OAK-D",
"Path to the folder containing the yaml files with the VIO parameters.");

int main(int argc, char* argv[]) {
// Initialize Google's flags library.
google::ParseCommandLineFlags(&argc, &argv, true);
Expand All @@ -139,7 +146,13 @@ int main(int argc, char* argv[]) {
"DisplayParams.yaml");

// Build dataset parser.
VIO::DataProviderInterface::Ptr dataset_parser = std::make_shared<VIO::OAKDataProvider>(vio_params);
VIO::DataProviderInterface::Ptr dataset_parser;
if(enableStereoFeature){
dataset_parser = std::make_shared<VIO::OAK3DFeatureDataProvider>(vio_params);
}
else{
dataset_parser = std::make_shared<VIO::OAKDataProvider>(vio_params);
}
CHECK(dataset_parser);

// ------------------------ VIO Pipeline Config ------------------------ //
Expand All @@ -152,6 +165,9 @@ int main(int argc, char* argv[]) {
case VIO::FrontendType::kStereoImu: {
vio_pipeline = VIO::make_unique<VIO::StereoImuPipeline>(vio_params);
} break;
case VIO::FrontendType::kRgbdImu: {
vio_pipeline = VIO::make_unique<VIO::RgbdImuPipeline>(vio_params);
} break;
default: {
LOG(FATAL) << "Unrecognized Frontend type: "
<< VIO::to_underlying(vio_params.frontend_type_)
Expand Down Expand Up @@ -186,20 +202,47 @@ int main(int argc, char* argv[]) {
stereo_pipeline,
std::placeholders::_1));
}
else if (vio_params.frontend_type_ == VIO::FrontendType::kRgbdImu) {
VIO::StereoImuPipeline::Ptr rgbd_pipeline =
VIO::safeCast<VIO::Pipeline, VIO::RgbdImuPipeline>(
vio_pipeline);

dataset_parser->registerDepthFrameCallback(
std::bind(&VIO::RgbdImuPipeline::fillDepthFrameQueue,
rgbd_pipeline,
std::placeholders::_1));
dataset_parser->registerFeatureTrackletsCallback(
std::bind(&VIO::RgbdImuPipeline::fillFeatureTrackletsQueue,
rgbd_pipeline,
std::placeholders::_1));

}



// ------------------------ The OAK's Pipeline ------------------------ //
dai::Pipeline pipeline = createPipeline();
auto daiDevice = std::make_shared<dai::Device>(pipeline);

auto leftQueue = daiDevice->getOutputQueue("left", 10, false);
auto rightQueue = daiDevice->getOutputQueue("right", 10, false);
auto imuQueue = daiDevice->getOutputQueue("imu", 10, false);

VIO::OAKDataProvider::Ptr oak_data_parser =
VIO::safeCast<VIO::DataProviderInterface, VIO::OAKDataProvider>(dataset_parser);

// ---------------------------ASYNC Launch-------------------------------- //
oak_data_parser->setQueues(leftQueue, rightQueue, imuQueue);
oak_data_parser->setLeftImuQueues(leftQueue, imuQueue);
if(enableStereoFeature){
auto depthQueue = daiDevice->getOutputQueue("depth", 10, false);
auto featureQueue = daiDevice->getOutputQueue("trackers", 10, false);
VIO::OAKDataProvider::Ptr oak_feature_data_parser =
VIO::safeCast<VIO::DataProviderInterface, VIO::OAK3DFeatureDataProvider>(dataset_parser);
oak_feature_data_parser->setDepthFeatureQueues(depthQueue, featureQueue);
}
else{
auto rightQueue = daiDevice->getOutputQueue("right", 10, false);
oak_data_parser->setRightQueue(rightQueue);
}

// Spin dataset.
auto tic = VIO::utils::Timer::tic();
Expand Down
3 changes: 2 additions & 1 deletion include/kimera-vio/dataprovider/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ target_sources(kimera_vio PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/DataProviderInterface.h"
"${CMAKE_CURRENT_LIST_DIR}/EurocDataProvider.h"
"${CMAKE_CURRENT_LIST_DIR}/OAKDataProvider.h"
# "${CMAKE_CURRENT_LIST_DIR}/KittiDataProvider.h"
"${CMAKE_CURRENT_LIST_DIR}/OAKStereoDataProvider.h"
"${CMAKE_CURRENT_LIST_DIR}/OAK3DFeatureDataProvider.h"
)
2 changes: 1 addition & 1 deletion include/kimera-vio/dataprovider/DataProviderInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <string>

#include "kimera-vio/frontend/Camera.h"
#include "kimera-vio/frontend/rgbd/RgbdFrame.h"
#include "kimera-vio/frontend/DepthFrame.h"
#include "kimera-vio/pipeline/Pipeline-definitions.h"
#include "kimera-vio/utils/Macros.h"

Expand Down
106 changes: 106 additions & 0 deletions include/kimera-vio/dataprovider/OAK3DFeatureDataProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* ----------------------------------------------------------------------------
* Copyright 2017, Massachusetts Institute of Technology,
* Cambridge, MA 02139
* All Rights Reserved
* Authors: Luca Carlone, et al. (see THANKS for the full author list)
* See LICENSE for the license information
* -------------------------------------------------------------------------- */

/**
* @file OAK3DFeatureDataProvider.h
* @brief Parse OAK Device Depth, Mono and Feature Streams
* @author Sachin Guruswamy
*/

#pragma once

#include <map>
#include <string>
#include <stack> // for syncing
#include <queue> // for syncing

#include <unordered_map> // for syncing
#include <vector>

#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/core/core.hpp>

#include "depthai/depthai.hpp"

#include <gtsam/base/Vector.h>
#include <gtsam/geometry/Cal3DS2.h>
#include <gtsam/geometry/Pose3.h>

#include "kimera-vio/common/VioNavState.h"
#include "kimera-vio/dataprovider/DataProviderInterface-definitions.h"
#include "kimera-vio/dataprovider/OAKDataProvider.h"
#include "kimera-vio/frontend/Frame.h"
#include "kimera-vio/frontend/StereoImuSyncPacket.h"
#include "kimera-vio/frontend/StereoMatchingParams.h"
#include "kimera-vio/logging/Logger.h"
#include "kimera-vio/utils/Macros.h"

namespace VIO {

/*
* Parse all images and camera calibration for an ETH dataset.
*/
class OAK3DFeatureDataProvider : public OAKDataProvider {
public:
KIMERA_DELETE_COPY_CONSTRUCTORS(OAK3DFeatureDataProvider);
KIMERA_POINTER_TYPEDEFS(OAK3DFeatureDataProvider);
EIGEN_MAKE_ALIGNED_OPERATOR_NEW

//! Ctor with params.
OAK3DFeatureDataProvider(const VioParams& vio_params);

// //! Ctor from gflags
// explicit OAKDataProvider(const VioParams& vio_params);

virtual ~OAK3DFeatureDataProvider();

void setDepthFeatureQueues(std::shared_ptr<dai::DataOutputQueue> depth_queue, std::shared_ptr<dai::DataOutputQueue> features_queue);


/**
* @brief spin Spins the dataset until it finishes. If set in sequential mode,
* it will return each time a frame is sent. In parallel mode, it will not
* return until it finishes.
* @return True if the dataset still has data, false otherwise.
*/
virtual bool spin() override;

/**
* @brief Callback to get the Image and Feature map to be added to
* a frame and send to the RGBDDataProviderModule.
*
*/
void leftImageFeatureCallback(std::shared_ptr<dai::ADatatype> image, std::shared_ptr<dai::ADatatype> feature_map);

/**
* @brief Callback to connect to get the depth image into pipeline
*
*/
void depthImageCallback(std::string name, std::shared_ptr<dai::ADatatype> data);

protected:
/**
* @brief spinOnce Send data to VIO pipeline on a per-frame basis
* @return if the dataset finished or not
*/
// virtual bool spinOnce();

void syncImageFeaturegrab(std::shared_ptr<dai::ADatatype> image, std::shared_ptr<dai::ADatatype> depth, std::shared_ptr<dai::ADatatype> feature_map);

protected:
VioParams vio_params_;
// TODO(Saching): move these to the backend Queues later.
std::queue<std::tuple<std::shared_ptr<dai::ADatatype>, std::shared_ptr<dai::ADatatype>, std::shared_ptr<dai::ADatatype>>> sync_msgs_;
std::queue<std::shared_ptr<dai::ADatatype>> left_sync_queue_, depth_sync_queue_, feature_sync_queue_;
std::shared_ptr<dai::DataOutputQueue> depth_queue_, feature_queue_;

// FIXME(Saching): Replace the EurocGtLogger later)
// EurocGtLogger::UniquePtr logger_;
};

} // namespace VIO
18 changes: 2 additions & 16 deletions include/kimera-vio/dataprovider/OAKDataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class OAKDataProvider : public DataProviderInterface {

virtual ~OAKDataProvider();

void setQueues(std::shared_ptr<dai::DataOutputQueue> left_queue, std::shared_ptr<dai::DataOutputQueue> right_queue, std::shared_ptr<dai::DataOutputQueue> imu_queue);
void setLeftImuQueues(std::shared_ptr<dai::DataOutputQueue> left_queue, std::shared_ptr<dai::DataOutputQueue> imu_queue);

/**
* @brief spin Spins the dataset until it finishes. If set in sequential mode,
Expand All @@ -96,12 +96,6 @@ void setQueues(std::shared_ptr<dai::DataOutputQueue> left_queue, std::shared_ptr
*/
void leftImageCallback(std::string name, std::shared_ptr<dai::ADatatype> data);

/**
* @brief Callback to connect to Undistorted right Queue
*
*/
void rightImageCallback(std::string name, std::shared_ptr<dai::ADatatype> data);

// // Retrieve absolute gt pose at *approx* timestamp.
// inline gtsam::Pose3 getGroundTruthPose(const Timestamp& timestamp) const {
// return getGroundTruthState(timestamp).pose_;
Expand All @@ -128,25 +122,17 @@ void setQueues(std::shared_ptr<dai::DataOutputQueue> left_queue, std::shared_ptr
// Get timestamp of a given pair of stereo images & IMU (synchronized).
Timestamp timestampAtFrame(const std::chrono::time_point<std::chrono::steady_clock, std::chrono::steady_clock::duration>& timestamp);

void syncImageSend(std::shared_ptr<dai::ADatatype> left_msg, std::shared_ptr<dai::ADatatype> right_msg);

protected:
VioParams vio_params_;
// TODO(Saching): move these to the backend Queues later.
std::stack<std::pair<std::shared_ptr<dai::ADatatype>, std::shared_ptr<dai::ADatatype>>> sync_msgs_;
std::queue<std::shared_ptr<dai::ADatatype>> left_sync_queue_, right_sync_queue_;

/// Images data.
// TODO(Toni): remove camera_names_ and camera_image_lists_...
// This matches the names of the folders in the dataset
std::vector<std::string> camera_names_;
CameraParams& left_cam_info_;
CameraParams& right_cam_info_;

//! Pre-stored imu-measurements
std::vector<ImuMeasurement> imu_measurements_;
ImuSyncMethod syncMode_ = ImuSyncMethod::LINEAR_INTERPOLATE_ACCEL;
std::shared_ptr<dai::DataOutputQueue> left_queue_, right_queue_, imu_queue_;
std::shared_ptr<dai::DataOutputQueue> left_queue_, imu_queue_;
// FIXME(Saching): Replace the EurocGtLogger later)
// EurocGtLogger::UniquePtr logger_;
};
Expand Down
Loading

0 comments on commit e94aaba

Please sign in to comment.