45 #pragma GCC diagnostic push 46 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 47 #pragma GCC diagnostic ignored "-Woverloaded-virtual" 48 #include <opencv2/opencv.hpp> 49 #pragma GCC diagnostic pop 50 #include <okvis/VioParametersReader.hpp> 51 #include <okvis/ThreadedKFVio.hpp> 52 #include <okvis/cameras/PinholeCamera.hpp> 53 #include <okvis/cameras/NoDistortion.hpp> 54 #include <okvis/cameras/RadialTangentialDistortion.hpp> 55 #include <okvis/cameras/EquidistantDistortion.hpp> 56 #include <okvis/cameras/RadialTangentialDistortion8.hpp> 57 #include <boost/filesystem.hpp> 63 class OkvisCallbackHandler
66 OkvisCallbackHandler()
70 Transform getLastTransform()
81 std::map<int, cv::Point3f> getLastLandmarks()
84 std::map<int, cv::Point3f> landmarks;
85 mutexLandmarks_.lock();
86 landmarks = landmarks_;
87 mutexLandmarks_.unlock();
92 void fullStateCallback(
93 const okvis::Time & t,
const okvis::kinematics::Transformation & T_WS,
94 const Eigen::Matrix<double, 9, 1> & ,
95 const Eigen::Matrix<double, 3, 1> & )
105 void landmarksCallback(
const okvis::Time & t,
106 const okvis::MapPointVector & landmarksVector,
107 const okvis::MapPointVector & )
110 mutexLandmarks_.lock();
112 for(
unsigned int i=0; i<landmarksVector.size(); ++i)
114 landmarks_.insert(std::make_pair((
int)landmarksVector[i].
id, cv::Point3f(landmarksVector[i].point[0], landmarksVector[i].point[1], landmarksVector[i].point[2])));
116 mutexLandmarks_.unlock();
122 Transform transform_;
123 std::map<int, cv::Point3f> landmarks_;
132 okvisCallbackHandler_(new OkvisCallbackHandler),
137 okvisParameters_(parameters),
144 UERROR(
"OKVIS config file is empty (%s)!", Parameters::kOdomOKVISConfigPath().c_str());
153 delete okvisEstimator_;
154 delete okvisCallbackHandler_;
166 delete okvisEstimator_;
170 imagesProcessed_ = 0;
173 delete okvisCallbackHandler_;
174 okvisCallbackHandler_ =
new OkvisCallbackHandler();
176 initGravity_ =
false;
191 okvis::Time timeOkvis = okvis::Time(data.
stamp());
193 bool imuUpdated =
false;
196 UDEBUG(
"IMU update stamp=%f acc=%f %f %f gyr=%f %f %f", data.
stamp(),
203 if(okvisEstimator_ != 0)
207 imuUpdated = okvisEstimator_->addImuMeasurement(timeOkvis, acc, ang);
211 UWARN(
"Ignoring IMU, waiting for an image to initialize...");
216 bool imageUpdated =
false;
220 std::vector<cv::Mat> images;
221 std::vector<CameraModel> models;
229 models.push_back(mleft);
237 UASSERT(R.cols==3 && R.rows == 3);
238 UASSERT(T.cols==1 && T.rows == 3);
239 Transform extrinsics(R.at<
double>(0,0), R.at<
double>(0,1), R.at<
double>(0,2), T.at<
double>(0,0),
240 R.at<
double>(1,0), R.at<
double>(1,1), R.at<
double>(1,2), T.at<
double>(1,0),
241 R.at<
double>(2,0), R.at<
double>(2,1), R.at<
double>(2,2), T.at<
double>(2,0));
253 models.push_back(mright);
259 for(
unsigned int i=0; i<data.
cameraModels().size(); ++i)
263 images.push_back(cv::Mat(data.
imageRaw(), cv::Rect(subImageWidth*i, 0, subImageWidth, data.
imageRaw().rows)));
275 if(okvisEstimator_ == 0)
280 UWARN(
"Ignoring Image, waiting for imu to initialize...");
284 okvis::VioParameters parameters;
287 UERROR(
"OKVIS config file is empty (%s)!", Parameters::kOdomOKVISConfigPath().c_str());
293 vio_parameters_reader.getParameters(parameters);
294 if(parameters.nCameraSystem.numCameras() > 0)
296 UWARN(
"Camera calibration included in OKVIS is ignored as calibration from received images will be used instead.");
298 parameters.nCameraSystem = okvis::cameras::NCameraSystem();
301 parameters.publishing.publishRate = parameters.imu.rate;
302 parameters.publishing.publishLandmarks =
true;
303 parameters.publishing.publishImuPropagatedState =
true;
304 parameters.publishing.landmarkQualityThreshold = 1.0e-2;
305 parameters.publishing.maxLandmarkQuality = 0.05;
306 parameters.publishing.trackedBodyFrame = okvis::FrameName::B;
307 parameters.publishing.velocitiesFrame = okvis::FrameName::B;
312 for(
unsigned int i=0; i<models.size(); ++i)
314 okvis::cameras::NCameraSystem::DistortionType distType = okvis::cameras::NCameraSystem::NoDistortion;
315 std::shared_ptr<const okvis::cameras::CameraBase>
cam;
318 if(models[i].D_raw().cols == 8)
320 okvis::cameras::RadialTangentialDistortion8 dist(
321 models[i].D_raw().at<double>(0,0),
322 models[i].D_raw().at<double>(0,1),
323 models[i].D_raw().at<double>(0,2),
324 models[i].D_raw().at<double>(0,3),
325 models[i].D_raw().at<double>(0,4),
326 models[i].D_raw().at<double>(0,5),
327 models[i].D_raw().at<double>(0,6),
328 models[i].D_raw().at<double>(0,7));
330 new okvis::cameras::PinholeCamera<okvis::cameras::RadialTangentialDistortion8>(
331 models[i].imageWidth(),
332 models[i].imageHeight(),
333 models[i].K_raw().at<double>(0,0),
334 models[i].K_raw().at<double>(1,1),
335 models[i].K_raw().at<double>(0,2),
336 models[i].K_raw().at<double>(1,2),
338 distType = okvis::cameras::NCameraSystem::RadialTangential8;
339 UINFO(
"RadialTangential8");
341 else if(models[i].D_raw().cols == 6)
343 okvis::cameras::EquidistantDistortion dist(
344 models[i].D_raw().at<double>(0,0),
345 models[i].D_raw().at<double>(0,1),
346 models[i].D_raw().at<double>(0,4),
347 models[i].D_raw().at<double>(0,5));
348 cam.reset(
new okvis::cameras::PinholeCamera<okvis::cameras::EquidistantDistortion>(
349 models[i].imageWidth(),
350 models[i].imageHeight(),
351 models[i].K_raw().at<double>(0,0),
352 models[i].K_raw().at<double>(1,1),
353 models[i].K_raw().at<double>(0,2),
354 models[i].K_raw().at<double>(1,2),
356 distType = okvis::cameras::NCameraSystem::Equidistant;
357 UINFO(
"Equidistant");
359 else if(models[i].D_raw().cols >= 4)
362 okvis::cameras::RadialTangentialDistortion dist(
363 models[i].D_raw().at<double>(0,0),
364 models[i].D_raw().at<double>(0,1),
365 models[i].D_raw().at<double>(0,2),
366 models[i].D_raw().at<double>(0,3));
368 new okvis::cameras::PinholeCamera<okvis::cameras::RadialTangentialDistortion>(
369 models[i].imageWidth(),
370 models[i].imageHeight(),
371 models[i].K_raw().at<double>(0,0),
372 models[i].K_raw().at<double>(1,1),
373 models[i].K_raw().at<double>(0,2),
374 models[i].K_raw().at<double>(1,2),
376 distType = okvis::cameras::NCameraSystem::RadialTangential;
377 UINFO(
"RadialTangential");
382 okvis::cameras::RadialTangentialDistortion dist(0,0,0,0);
384 new okvis::cameras::PinholeCamera<okvis::cameras::RadialTangentialDistortion>(
385 models[i].imageWidth(),
386 models[i].imageHeight(),
387 models[i].K().at<double>(0,0),
388 models[i].K().at<double>(1,1),
389 models[i].K().at<double>(0,2),
390 models[i].K().at<double>(1,2),
392 distType = okvis::cameras::NCameraSystem::RadialTangential;
397 UINFO(
"model %d: %s", i, models[i].localTransform().prettyPrint().c_str());
399 Eigen::Vector3d r(models[i].localTransform().x(), models[i].localTransform().y(), models[i].localTransform().z());
400 parameters.nCameraSystem.addCamera(
401 std::shared_ptr<const okvis::kinematics::Transformation>(
new okvis::kinematics::Transformation(r, models[i].localTransform().getQuaterniond().normalized())),
407 okvisEstimator_ =
new okvis::ThreadedKFVio(parameters);
409 okvisEstimator_->setFullStateCallback(
410 std::bind(&OkvisCallbackHandler::fullStateCallback, okvisCallbackHandler_,
411 std::placeholders::_1, std::placeholders::_2,
412 std::placeholders::_3, std::placeholders::_4));
414 okvisEstimator_->setLandmarksCallback(
415 std::bind(&OkvisCallbackHandler::landmarksCallback, okvisCallbackHandler_,
416 std::placeholders::_1, std::placeholders::_2,
417 std::placeholders::_3));
419 okvisEstimator_->setBlocking(
true);
422 for(
unsigned int i=0; i<images.size(); ++i)
425 if(images[i].type() == CV_8UC3)
427 cv::cvtColor(images[i], gray, CV_BGR2GRAY);
429 else if(images[i].type() == CV_8UC1)
435 UFATAL(
"Not supported color type!");
438 imageUpdated = okvisEstimator_->addImage(timeOkvis, i, gray);
441 UWARN(
"Image update with stamp %f delayed...", data.
stamp());
451 if((imageUpdated || imuUpdated) && imagesProcessed_ > 10)
453 Transform fixPos(-1,0,0,0, 0,-1,0,0, 0,0,1,0);
454 Transform fixRot(0,0,1,0, 0,-1,0,0, 1,0,0,0);
455 Transform p = okvisCallbackHandler_->getLastTransform();
458 p = fixPos * p * fixRot;
495 UERROR(
"RTAB-Map is not built with OKVIS support! Select another visual odometry approach.");
void setLocalTransform(const Transform &transform)
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
rtabmap::CameraThread * cam
unsigned int framesProcessed() const
virtual Transform computeTransform(SensorData &image, const Transform &guess=Transform(), OdometryInfo *info=0)
const cv::Mat & R() const
bool imagesAlreadyRectified() const
virtual void reset(const Transform &initialPose=Transform::getIdentity())
std::map< std::string, std::string > ParametersMap
const Transform & getPose() const
const cv::Mat & imageRaw() const
#define UASSERT(condition)
Wrappers of STL for convenient functions.
bool isValidForProjection() const
const CameraModel & left() const
const cv::Vec3d linearAcceleration() const
const cv::Mat & T() const
const std::vector< CameraModel > & cameraModels() const
virtual void reset(const Transform &initialPose=Transform::getIdentity())
const Transform & localTransform() const
const CameraModel & right() const
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
std::string configFilename_
OdometryOkvis(const rtabmap::ParametersMap ¶meters=rtabmap::ParametersMap())
const cv::Vec3d & angularVelocity() const
const Transform & localTransform() const