123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- using namespace std;
- class ImuGrabber
- {
- public:
- ImuGrabber(){};
- void GrabImu(const sensor_msgs::ImuConstPtr &imu_msg);
- queue<sensor_msgs::ImuConstPtr> imuBuf;
- std::mutex mBufMutex;
- };
- class ImageGrabber
- {
- public:
- ImageGrabber(ORB_SLAM3::System* pSLAM, ImuGrabber *pImuGb, const bool bRect, const bool bClahe): mpSLAM(pSLAM), mpImuGb(pImuGb), do_rectify(bRect), mbClahe(bClahe){}
- void GrabImageLeft(const sensor_msgs::ImageConstPtr& msg);
- void GrabImageRight(const sensor_msgs::ImageConstPtr& msg);
- cv::Mat GetImage(const sensor_msgs::ImageConstPtr &img_msg);
- void SyncWithImu();
- queue<sensor_msgs::ImageConstPtr> imgLeftBuf, imgRightBuf;
- std::mutex mBufMutexLeft,mBufMutexRight;
-
- ORB_SLAM3::System* mpSLAM;
- ImuGrabber *mpImuGb;
- const bool do_rectify;
- cv::Mat M1l,M2l,M1r,M2r;
- const bool mbClahe;
- cv::Ptr<cv::CLAHE> mClahe = cv::createCLAHE(3.0, cv::Size(8, 8));
- };
- int main(int argc, char **argv)
- {
- ros::init(argc, argv, "Stereo_Inertial");
- ros::NodeHandle n("~");
- ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Info);
- bool bEqual = false;
- if(argc < 4 || argc > 5)
- {
- cerr << endl << "Usage: rosrun ORB_SLAM3 Stereo_Inertial path_to_vocabulary path_to_settings do_rectify [do_equalize]" << endl;
- ros::shutdown();
- return 1;
- }
- std::string sbRect(argv[3]);
- if(argc==5)
- {
- std::string sbEqual(argv[4]);
- if(sbEqual == "true")
- bEqual = true;
- }
-
- ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_STEREO,true);
- ImuGrabber imugb;
- ImageGrabber igb(&SLAM,&imugb,sbRect == "true",bEqual);
-
- if(igb.do_rectify)
- {
-
- cv::FileStorage fsSettings(argv[2], cv::FileStorage::READ);
- if(!fsSettings.isOpened())
- {
- cerr << "ERROR: Wrong path to settings" << endl;
- return -1;
- }
- cv::Mat K_l, K_r, P_l, P_r, R_l, R_r, D_l, D_r;
- fsSettings["LEFT.K"] >> K_l;
- fsSettings["RIGHT.K"] >> K_r;
- fsSettings["LEFT.P"] >> P_l;
- fsSettings["RIGHT.P"] >> P_r;
- fsSettings["LEFT.R"] >> R_l;
- fsSettings["RIGHT.R"] >> R_r;
- fsSettings["LEFT.D"] >> D_l;
- fsSettings["RIGHT.D"] >> D_r;
- int rows_l = fsSettings["LEFT.height"];
- int cols_l = fsSettings["LEFT.width"];
- int rows_r = fsSettings["RIGHT.height"];
- int cols_r = fsSettings["RIGHT.width"];
- if(K_l.empty() || K_r.empty() || P_l.empty() || P_r.empty() || R_l.empty() || R_r.empty() || D_l.empty() || D_r.empty() ||
- rows_l==0 || rows_r==0 || cols_l==0 || cols_r==0)
- {
- cerr << "ERROR: Calibration parameters to rectify stereo are missing!" << endl;
- return -1;
- }
- cv::initUndistortRectifyMap(K_l,D_l,R_l,P_l.rowRange(0,3).colRange(0,3),cv::Size(cols_l,rows_l),CV_32F,igb.M1l,igb.M2l);
- cv::initUndistortRectifyMap(K_r,D_r,R_r,P_r.rowRange(0,3).colRange(0,3),cv::Size(cols_r,rows_r),CV_32F,igb.M1r,igb.M2r);
- }
-
- ros::Subscriber sub_imu = n.subscribe("/imu", 1000, &ImuGrabber::GrabImu, &imugb);
- ros::Subscriber sub_img_left = n.subscribe("/camera/left/image_raw", 100, &ImageGrabber::GrabImageLeft,&igb);
- ros::Subscriber sub_img_right = n.subscribe("/camera/right/image_raw", 100, &ImageGrabber::GrabImageRight,&igb);
- std::thread sync_thread(&ImageGrabber::SyncWithImu,&igb);
- ros::spin();
- return 0;
- }
- void ImageGrabber::GrabImageLeft(const sensor_msgs::ImageConstPtr &img_msg)
- {
- mBufMutexLeft.lock();
- if (!imgLeftBuf.empty())
- imgLeftBuf.pop();
- imgLeftBuf.push(img_msg);
- mBufMutexLeft.unlock();
- }
- void ImageGrabber::GrabImageRight(const sensor_msgs::ImageConstPtr &img_msg)
- {
- mBufMutexRight.lock();
- if (!imgRightBuf.empty())
- imgRightBuf.pop();
- imgRightBuf.push(img_msg);
- mBufMutexRight.unlock();
- }
- cv::Mat ImageGrabber::GetImage(const sensor_msgs::ImageConstPtr &img_msg)
- {
-
- cv_bridge::CvImageConstPtr cv_ptr;
- try
- {
- cv_ptr = cv_bridge::toCvShare(img_msg, sensor_msgs::image_encodings::MONO8);
- }
- catch (cv_bridge::Exception& e)
- {
- ROS_ERROR("cv_bridge exception: %s", e.what());
- }
-
- if(cv_ptr->image.type()==0)
- {
- return cv_ptr->image.clone();
- }
- else
- {
- std::cout << "Error type" << std::endl;
- return cv_ptr->image.clone();
- }
- }
- void ImageGrabber::SyncWithImu()
- {
- const double maxTimeDiff = 0.01;
- while(1)
- {
- cv::Mat imLeft, imRight;
- double tImLeft = 0, tImRight = 0;
- if (!imgLeftBuf.empty()&&!imgRightBuf.empty()&&!mpImuGb->imuBuf.empty())
- {
- tImLeft = imgLeftBuf.front()->header.stamp.toSec();
- tImRight = imgRightBuf.front()->header.stamp.toSec();
- this->mBufMutexRight.lock();
- while((tImLeft-tImRight)>maxTimeDiff && imgRightBuf.size()>1)
- {
- imgRightBuf.pop();
- tImRight = imgRightBuf.front()->header.stamp.toSec();
- }
- this->mBufMutexRight.unlock();
- this->mBufMutexLeft.lock();
- while((tImRight-tImLeft)>maxTimeDiff && imgLeftBuf.size()>1)
- {
- imgLeftBuf.pop();
- tImLeft = imgLeftBuf.front()->header.stamp.toSec();
- }
- this->mBufMutexLeft.unlock();
- if((tImLeft-tImRight)>maxTimeDiff || (tImRight-tImLeft)>maxTimeDiff)
- {
-
- continue;
- }
- if(tImLeft>mpImuGb->imuBuf.back()->header.stamp.toSec())
- continue;
- this->mBufMutexLeft.lock();
- imLeft = GetImage(imgLeftBuf.front());
- imgLeftBuf.pop();
- this->mBufMutexLeft.unlock();
- this->mBufMutexRight.lock();
- imRight = GetImage(imgRightBuf.front());
- imgRightBuf.pop();
- this->mBufMutexRight.unlock();
- vector<ORB_SLAM3::IMU::Point> vImuMeas;
- mpImuGb->mBufMutex.lock();
- if(!mpImuGb->imuBuf.empty())
- {
-
- vImuMeas.clear();
- while(!mpImuGb->imuBuf.empty() && mpImuGb->imuBuf.front()->header.stamp.toSec()<=tImLeft)
- {
- double t = mpImuGb->imuBuf.front()->header.stamp.toSec();
- cv::Point3f acc(mpImuGb->imuBuf.front()->linear_acceleration.x, mpImuGb->imuBuf.front()->linear_acceleration.y, mpImuGb->imuBuf.front()->linear_acceleration.z);
- cv::Point3f gyr(mpImuGb->imuBuf.front()->angular_velocity.x, mpImuGb->imuBuf.front()->angular_velocity.y, mpImuGb->imuBuf.front()->angular_velocity.z);
- vImuMeas.push_back(ORB_SLAM3::IMU::Point(acc,gyr,t));
- mpImuGb->imuBuf.pop();
- }
- }
- mpImuGb->mBufMutex.unlock();
- if(mbClahe)
- {
- mClahe->apply(imLeft,imLeft);
- mClahe->apply(imRight,imRight);
- }
- if(do_rectify)
- {
- cv::remap(imLeft,imLeft,M1l,M2l,cv::INTER_LINEAR);
- cv::remap(imRight,imRight,M1r,M2r,cv::INTER_LINEAR);
- }
- mpSLAM->TrackStereo(imLeft,imRight,tImLeft,vImuMeas);
- std::chrono::milliseconds tSleep(1);
- std::this_thread::sleep_for(tSleep);
- }
- }
- }
- void ImuGrabber::GrabImu(const sensor_msgs::ImuConstPtr &imu_msg)
- {
- mBufMutex.lock();
- imuBuf.push(imu_msg);
- mBufMutex.unlock();
- return;
- }
|