Open astronaut71 opened 1 year ago
Hi I created monocular inertial node . I used ROS2 humble and can build the node. But when run it can not see the image. Here the node
... using namespace std; class ImuGrabber { public: ImuGrabber(){}; void GrabImu(const sensor_msgs::msg::Imu::SharedPtr imu_msg); queue<sensor_msgs::msg::Imu::SharedPtr> imuBuf; std::mutex mBufMutex; }; class ImageGrabber { public: ImageGrabber(ORB_SLAM3::System* pSLAM, ImuGrabber *pImuGb, const bool bClahe): mpSLAM(pSLAM), mpImuGb(pImuGb), mbClahe(bClahe){} void GrabImage(const sensor_msgs::msg::Image::SharedPtr img_msg); cv::Mat GetImage(const sensor_msgs::msg::Image::SharedPtr img_msg); void SyncWithImu(); //method for setting ROS publisher void SetPub(rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr pub); queue<sensor_msgs::msg::Image::SharedPtr> img0Buf; std::mutex mBufMutex; ORB_SLAM3::System* mpSLAM; ImuGrabber *mpImuGb; //additional variables for publishing pose & broadcasting transform - https://roboticsknowledgebase.com/wiki/state-estimation/orb-slam2-setup/ cv::Mat m1, m2; bool do_rectify, pub_tf, pub_pose; rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr orb_pub; std::unique_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster_; const bool mbClahe; cv::Ptr<cv::CLAHE> mClahe = cv::createCLAHE(3.0, cv::Size(8, 8)); }; class MonoInertial : public rclcpp::Node { public: MonoInertial(const std::string& vocabulary_path, const std::string& settings_path, bool do_equalize) : Node("Mono_Inertial") { RCLCPP_INFO(this->get_logger(), "Mono_Inertial node started"); // Create SLAM system. It initializes all system threads and gets ready to process frames. SLAM_ = new ORB_SLAM3::System(vocabulary_path, settings_path, ORB_SLAM3::System::IMU_MONOCULAR, true); imugb_ = new ImuGrabber(); igb_ = new ImageGrabber(SLAM_, imugb_, do_equalize); pose_pub_ = this->create_publisher<geometry_msgs::msg::PoseStamped>("orb_pose", 100); // Maximum delay, 5 seconds sub_imu_ = this->create_subscription<sensor_msgs::msg::Imu>( "/anafi/drone/linear_acceleration", 10, [&](const sensor_msgs::msg::Imu::SharedPtr msg) { imugb_->GrabImu(msg); }); sub_img0_ = this->create_subscription<sensor_msgs::msg::Image>( "/anafi/camera/image", 1, [&](const sensor_msgs::msg::Image::SharedPtr msg) { igb_->GrabImage(msg); }); // Initialize the transform broadcaster // Create publisher igb_->SetPub(pose_pub_); sync_thread_ = std::thread(&ImageGrabber::SyncWithImu, igb_); } private: ORB_SLAM3::System* SLAM_; ImuGrabber* imugb_; ImageGrabber* igb_; rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr pose_pub_; rclcpp::Subscription<sensor_msgs::msg::Imu>::SharedPtr sub_imu_; rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr sub_img0_; std::thread sync_thread_; }; int main(int argc, char **argv) { rclcpp::init(argc, argv); bool do_equalize = false; if (argc < 3 || argc > 4) { RCLCPP_ERROR(rclcpp::get_logger("Mono_Inertial"), "Usage: ros2 run ORB_SLAM3 Mono_Inertial path_to_vocabulary path_to_settings [do_equalize]"); rclcpp::shutdown(); return 1; } if(argc==4) { std::string sbEqual(argv[3]); if (sbEqual == "true") do_equalize = true; } auto node = std::make_shared<MonoInertial>(argv[1], argv[2], do_equalize); rclcpp::spin(node); rclcpp::shutdown(); return 0; } //method for assigning publisher void ImageGrabber::SetPub(rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr pub) { orb_pub = pub; } void ImageGrabber::GrabImage(const sensor_msgs::msg::Image::SharedPtr img_msg) { mBufMutex.lock(); if (!img0Buf.empty()) img0Buf.pop(); img0Buf.push(img_msg); mBufMutex.unlock(); } cv::Mat ImageGrabber::GetImage(const sensor_msgs::msg::Image::SharedPtr img_msg) { // Copy the ros image message to cv::Mat. cv_bridge::CvImageConstPtr cv_ptr; try { cv_ptr = cv_bridge::toCvShare(img_msg, sensor_msgs::image_encodings::RGB8); } catch (cv_bridge::Exception& e) { RCLCPP_ERROR(rclcpp::get_logger("Mono_Inertial"), "cv_bridge exception: %s", e.what()); } if(cv_ptr->image.type()==0) { return cv_ptr->image.clone(); } else { RCLCPP_ERROR(rclcpp::get_logger("Mono_Inertial"), "Error image type"); return cv_ptr->image.clone(); } } void ImageGrabber::SyncWithImu() { //while(1) while (rclcpp::ok()) { cv::Mat im; double tIm = 0; if (!img0Buf.empty()&&!mpImuGb->imuBuf.empty()) { tIm = img0Buf.front()->header.stamp.sec + img0Buf.front()->header.stamp.nanosec * 1e-9; if (tIm > mpImuGb->imuBuf.back()->header.stamp.sec + mpImuGb->imuBuf.back()->header.stamp.nanosec * 1e-9) continue; { this->mBufMutex.lock(); im = GetImage(img0Buf.front()); img0Buf.pop(); this->mBufMutex.unlock(); } vector<ORB_SLAM3::IMU::Point> vImuMeas; mpImuGb->mBufMutex.lock(); if(!mpImuGb->imuBuf.empty()) { // Load imu measurements from buffer vImuMeas.clear(); while (!mpImuGb->imuBuf.empty() && mpImuGb->imuBuf.front()->header.stamp.sec + mpImuGb->imuBuf.front()->header.stamp.nanosec * 1e-9 <= tIm) { double t = mpImuGb->imuBuf.front()->header.stamp.sec + mpImuGb->imuBuf.front()->header.stamp.nanosec * 1e-9; 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(im,im); cv::Mat T_, R_, t_ ; //stores return variable of TrackMonocular mpSLAM->TrackMonocular(im, tIm, vImuMeas); //this line seems to break things //aftermarket publish function if (pub_tf || pub_pose) { if (!(T_.empty())) { cv::Size s = T_.size(); if ((s.height >= 3) && (s.width >= 3)) { R_ = T_.rowRange(0,3).colRange(0,3).t(); t_ = -R_*T_.rowRange(0,3).col(3); std::vector<float> q = ORB_SLAM3::Converter::toQuaternion(R_); float scale_factor=1.0; tf2::Transform tf_transform; tf_transform.setOrigin(tf2::Vector3(t_.at<float>(0, 0) * scale_factor, t_.at<float>(0, 1) * scale_factor, t_.at<float>(0, 2) * scale_factor)); tf_transform.setRotation(tf2::Quaternion(q[0], q[1], q[2], q[3])); // Broadcast the transform if (pub_tf) { geometry_msgs::msg::TransformStamped tf_msg; tf_msg.header.stamp = rclcpp::Time(tIm); tf_msg.header.frame_id = "/camera"; tf_msg.child_frame_id = "ORB_SLAM3_MONO_INERTIAL"; tf_msg.transform = tf2::toMsg(tf_transform); tf_broadcaster_->sendTransform(tf_msg); } if (pub_pose) { geometry_msgs::msg::PoseStamped pose; pose.header.stamp = rclcpp::Time(tIm); //pose.header.stamp = img0Buf.front()->header.stamp; pose.header.frame_id ="ORB_SLAM3_MONO_INERTIAL"; //pose.pose = tf2::toMsg(tf_transform); tf2::toMsg(tf_transform, pose.pose); orb_pub->publish(pose); } } } } } std::chrono::milliseconds tSleep(1); std::this_thread::sleep_for(tSleep); } } void ImuGrabber::GrabImu(const sensor_msgs::msg::Imu::SharedPtr imu_msg) { mBufMutex.lock(); imuBuf.push(imu_msg); mBufMutex.unlock(); return; }
Any reason why?
Please use Markdown to format your posting appropriately. Github even has a GUI for that.
done it. Better now. Sorry was just in rush to post it
Hi I created monocular inertial node . I used ROS2 humble and can build the node. But when run it can not see the image. Here the node
Any reason why?