From 129ed8c4c8bb4adc41f87c46860e05ee58893169 Mon Sep 17 00:00:00 2001 From: Cesar Debeunne <cdebeunne@nilgiri.laas.fr> Date: Fri, 6 Aug 2021 17:31:36 +0200 Subject: [PATCH] parsing with rosbags --- .gitignore | 1 + demos/CMakeLists.txt | 27 +- demos/cosyslam.cpp | 230 ++++++------------ .../processor_tracker_landmark_object.cpp | 5 +- 4 files changed, 111 insertions(+), 152 deletions(-) diff --git a/.gitignore b/.gitignore index 234d870..c8958c5 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ src/examples/map_polyline_example_write.yaml /Default/ *.csv +*.bag *.csv# results_* diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt index 6620c03..a53c11a 100644 --- a/demos/CMakeLists.txt +++ b/demos/CMakeLists.txt @@ -1,15 +1,40 @@ -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR} + ${catkin_INCLUDE_DIRS} +) + +FIND_PACKAGE(catkin REQUIRED COMPONENTS + rosbag + rosconsole + roscpp + roslib + sensor_msgs + std_msgs + geometry_msgs + tf + wolf_ros_objectslam + wolf_ros_node +) + +INCLUDE_DIRECTORIES( + ${rosbag_INCLUDE_DIRS} + ${wolf_ros_objectslam_INCLUDE_DIRS} + ${std_msgs_INCLUDE_DIRS} +) + ADD_EXECUTABLE(demo_toy_pbe demo_toy_pbe.cpp) TARGET_LINK_LIBRARIES(demo_toy_pbe ${wolfcore_LIBRARIES} ${PLUGIN_NAME} + ${catkin_LIBRARIES} ) ADD_EXECUTABLE(cosyslam cosyslam.cpp) TARGET_LINK_LIBRARIES(cosyslam ${wolfcore_LIBRARIES} ${PLUGIN_NAME} + ${catkin_LIBRARIES} ) diff --git a/demos/cosyslam.cpp b/demos/cosyslam.cpp index a8379b7..1fd5816 100644 --- a/demos/cosyslam.cpp +++ b/demos/cosyslam.cpp @@ -16,6 +16,14 @@ #include "objectslam/internal/config.h" #include "objectslam/landmark/landmark_object.h" +#include <rosbag/bag.h> +#include <rosbag/view.h> +#include <wolf_ros_objectslam/CosyObjectArray.h> +#include <wolf_ros_objectslam/CosyObject.h> +#include <std_msgs/Header.h> +#include <boost/foreach.hpp> +#define foreach BOOST_FOREACH + using namespace wolf; using namespace Eigen; @@ -31,97 +39,13 @@ Vector7d isometry_to_posevec(Isometry3d M) return pose_vec; } -std::vector<std::pair<std::string, std::vector<std::string>>> read_csv(std::string filename) -{ - // create an input filestream - std::ifstream myFile(filename); - - // Create a vector of <string, int vector> pairs to store the result - std::vector<std::pair<std::string, std::vector<std::string>>> result; - - // Make sure the file is open - if (!myFile.is_open()) - throw std::runtime_error("Could not open file"); - - // Variables - std::string line, colname, val; - - // read the columns name - if (myFile.good()) - { - - // extract the first line in the file - std::getline(myFile, line); - - // Create a stringstream from line - std::stringstream ss(line); - - // Extract each column name - while (std::getline(ss, colname, ',')) - { - - // Initialize and add <colname, string vector> pairs to result - result.push_back({colname, std::vector<std::string>{}}); - } - } - - // Read data, line by line - while (std::getline(myFile, line)) - { - // Create a stringstream of the current line - std::stringstream ss(line); - - // Keep track of the current column index - int colIdx = 0; - - // Extract each string and store it in result - while (std::getline(ss, val, ',')) - { - result.at(colIdx).second.push_back(val); - colIdx++; - } - } - - // Close file - myFile.close(); - - return result; -} - -Isometry3d str_to_isometry(std::string pose) -{ - // Let's initialize the eigen objects - Matrix4d pose_matrix; - - // Parse the string - std::string::size_type sz; - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 4; j++) - { - pose_matrix(i, j) = std::stod(pose, &sz); - pose = pose.substr(sz); - } - } - - // Create the transformation - Isometry3d trans; - trans.linear() = pose_matrix.topLeftCorner(3, 3); - trans.translation() = pose_matrix.topRightCorner(3, 1); - - return trans; -} - int main() { - ///////////////////////// - // read the input data // - ///////////////////////// - + // Rosbag opening + rosbag::Bag bag; std::string wolf_root = _WOLF_OBJECTSLAM_ROOT_DIR; - std::string filename = wolf_root + "/demos/input_demoMulti.csv"; - std::vector<std::pair<std::string, std::vector<std::string>>> csv_values; - csv_values = read_csv(filename); + std::string bagpath = wolf_root + "/demos/demoMulti.bag"; + bag.open(bagpath, rosbag::bagmode::Read); //////////////////////////// // setup the wolf problem // @@ -138,61 +62,55 @@ int main() VectorComposite x0("PO", {Vector3d(0, 0, 0), Quaterniond::Identity().coeffs()}); VectorComposite sig0("PO", {Vector3d(1, 1, 1), Vector3d(1, 1, 1)}); - FrameBasePtr F1 = problem->setPriorFactor(x0, sig0, 0.0, 0.1); ObjectDetections dets; - // Parsing variables - int len = csv_values.at(0).second.size(); - int idx_pose = 4; - int idx_obj = 3; - int idx_t = 9; - int idx_s = 6; - /////////////// // SLAM loop // /////////////// - double t_cur = 0; + std::vector<std::string> topics; + topics.push_back(std::string("/cosypose")); + rosbag::View view(bag, rosbag::TopicQuery(topics)); + ros::Time bag_begin_time = view.getBeginTime(); + TimeStamp init_ts(bag_begin_time.toSec()); + FrameBasePtr F1 = problem->setPriorFactor(x0, sig0, init_ts, 0.1); + + // Variables init + Matrix6d cov; + Vector6d sig; + Vector7d poseVec; int number_of_kf = 0; int counter = 0; + int frame_id = 0; + - for (int i = 0; i < len; i++) + foreach(rosbag::MessageInstance const m, view) { - std::cout << i << std::endl; - - // Measurement data - Isometry3d c_M_o = str_to_isometry(csv_values.at(idx_pose).second.at(i)); - Matrix6d cov; - Vector6d sig; - // default covariance value : the real value is computed in the processor - sig << 0.02, 0.02, 0.02, 0.1, 0.1, 0.1; - cov = sig.array().matrix().asDiagonal(); - std::string object_name; - object_name = csv_values.at(idx_obj).second.at(i); - double t; - t = std::stod(csv_values.at(idx_t).second.at(i)); - double s; - s = std::stod(csv_values.at(idx_s).second.at(i)); - ObjectDetection det = {.measurement = isometry_to_posevec(c_M_o), .detection_score = s, .meas_cov = cov, .object_type = object_name}; - - if (t == t_cur){ - // Capture on the current frame - dets.push_back(det); - } else if (i == len-1){ - // Capture on the last frame - dets.push_back(det); - CaptureObjectPtr cap = std::make_shared<CaptureObject>(t_cur, sen, dets); + std::cout << "--------FRAME " << frame_id << "-------------" << std::endl; + + wolf_ros_objectslam::CosyObjectArray::ConstPtr cosyArray = m.instantiate<wolf_ros_objectslam::CosyObjectArray>(); + if (cosyArray != nullptr){ + for (auto object : cosyArray->objects){ + poseVec << object.pose.position.x, + object.pose.position.y, + object.pose.position.z, + object.pose.orientation.x, + object.pose.orientation.y, + object.pose.orientation.z, + object.pose.orientation.w; + + // default covariance value : the real value is computed in the processor + sig << 0.02, 0.02, 0.02, 0.05, 0.05, 0.05; + cov = sig.array().matrix().asDiagonal(); + ObjectDetection det = {.measurement = poseVec, .detection_score = object.score, .meas_cov = cov, .object_type = object.name}; + dets.push_back(det); + } + TimeStamp ts(cosyArray->header.stamp.sec, cosyArray->header.stamp.nsec); + CaptureObjectPtr cap = std::make_shared<CaptureObject>(ts, sen, dets); cap->process(); - } else { - // Capture on a new frame - CaptureObjectPtr cap = std::make_shared<CaptureObject>(t_cur, sen, dets); - cap->process(); - dets.clear(); - dets.push_back(det); } - t_cur = t; // Solve if a KF was voted number_of_kf = problem->getTrajectory()->getFrameMap().size(); @@ -200,8 +118,15 @@ int main() std::string report = solver->solve(SolverCeres::ReportVerbosity::FULL); counter++; } + frame_id ++; } + bag.close(); + + ////////////////////// + // results analysis // + ////////////////////// + std::string report = solver->solve(SolverCeres::ReportVerbosity::FULL); std::cout << report << std::endl; @@ -223,7 +148,7 @@ int main() file_res << header_res; std::string header_map = "id,px,py,pz,qx,qy,qz,qw,\n"; file_map << header_map; - std::string header_init = "id,ts,object_id,pose,\n"; + std::string header_init = "id,ts,object_id,pose,image_coord,\n"; file_init << header_init; VectorComposite state_est; @@ -254,25 +179,32 @@ int main() for (auto& lmk: problem->getMap()->getLandmarkList()){ auto lmk_obj = std::dynamic_pointer_cast<LandmarkObject>(lmk); - if (good_lmk == 0 || good_lmk == 1 || good_lmk == 2){ - // World to lmk - state_lmk = lmk->getState(); - Vector7d pose_lmk; - pose_lmk << state_lmk['P'], state_lmk['O']; - Isometry3d w_M_lmk = posevec_to_isometry(pose_lmk); - - // Cam to lmk - Isometry3d c_M_lmk = w_M_c.inverse() * w_M_lmk; - - file_init << counter << "," - << t << "," - << lmk_obj->getObjectType() << "," - << c_M_lmk.matrix().row(0) << " " - << c_M_lmk.matrix().row(1) << " " - << c_M_lmk.matrix().row(2) << " " - << c_M_lmk.matrix().row(3) << " " - << "\n"; - } + // World to lmk + state_lmk = lmk_obj->getState(); + Vector7d pose_lmk; + pose_lmk << state_lmk['P'], state_lmk['O']; + Isometry3d w_M_lmk = posevec_to_isometry(pose_lmk); + + // Cam to lmk + Isometry3d c_M_lmk = w_M_c.inverse() * w_M_lmk; + + // coordinates of the object in the image + Matrix3d intrinsic = lmk_obj->getIntrinsic(); + Vector3d c_t_lmk = c_M_lmk.translation(); + Vector3d image_coord = intrinsic * c_t_lmk; + image_coord = image_coord/image_coord(2); + + file_init << 3*counter << "," + << t << "," + << lmk_obj->getObjectType() << "," + << c_M_lmk.matrix().row(0) << " " + << c_M_lmk.matrix().row(1) << " " + << c_M_lmk.matrix().row(2) << " " + << c_M_lmk.matrix().row(3) << " ," + << image_coord(0) << " " + << image_coord(1) << " " + << "\n"; + good_lmk++; } counter++; diff --git a/src/processor/processor_tracker_landmark_object.cpp b/src/processor/processor_tracker_landmark_object.cpp index 9cd9347..a5c33ed 100644 --- a/src/processor/processor_tracker_landmark_object.cpp +++ b/src/processor/processor_tracker_landmark_object.cpp @@ -214,7 +214,7 @@ unsigned int ProcessorTrackerLandmarkObject::detectNewFeatures(const int& _max_n double e_pos = (pos_lmk - pos_feat).norm(); double e_rot = log_q(quat_lmk.conjugate() * quat_feat).norm(); - if (e_pos < e_pos_thr_+0.08 && e_rot < e_rot_thr_+0.08){ + if (e_pos < e_pos_thr_+0.1 && e_rot < e_rot_thr_+0.1){ feature_already_found = true; break; } @@ -223,12 +223,13 @@ unsigned int ProcessorTrackerLandmarkObject::detectNewFeatures(const int& _max_n if (!feature_already_found) { + std::cout << feat_obj->getObjectType() << std::endl; // If the feature is not in the map & not in the list of newly detected features yet, then we add it. _features_out.push_back(feat); // link feature (they are created unlinked in preprocess()) feat->link(_capture); - + break; } } -- GitLab