couldn't read PipelineParams.yaml file with segmentation fault
Description: I have successfully built the whole ros project without any error come out.
but when I run roscore, and then run
rviz -d $(rospack find kimera_vio_ros)/rviz/kimera_vio_euroc.rviz
roslaunch kimera_vio_ros kimera_vio_ros_euroc.launch
it will occurs a segmentation fault with reading .yaml.
I suspect it is a problem with opencv, so I write a small exmaple mimic with the implement of YamlParser.h, it works, I could read the .yaml file with CHECK_NOTNULL(fs)->open(filename, cv::FileStorage::READ);
however, In Kimera-VIO-ROS, we just couldn't read this catkin_ws/src/Kimera-VIO/params/Euroc/PipelineParams.yaml there is only one Opencv in my PC, that is 3.4.0, I have check the version of opencv when I build them, both are 3.4.0
Command:
roslaunch kimera_vio_ros kimera_vio_ros_euroc.launch
process[kimera_vio_ros/kimera_vio_ros_node-1]: started with pid [1078237] process[kimera_vio_ros/posegraph_viewer-2]: started with pid [1078238] [ INFO] [1733959322.787804313]: Initializing pose graph visualizer ================================================================================REQUIRED process [kimera_vio_ros/kimera_vio_ros_node-1] has died!
Additional files: Please attach all the files needed to reproduce the error.
Please give also the following information:
- KimeraVIO branch, tag or commit used
- GTSAM version used: 4.2.0
- OpenGV version used:
- OpenCV version used: type
opencv_version3.4.0 - Operating system and version (e.g. Ubuntu 16.04 or Windows 10): Ubuntu 20.04
- Did you change the source code? (yes / no): no
this is my small example, it works in environment of Opencv 3.4.0
#include <opencv2/core.hpp>
#include <iostream>
#include <string>
#include <glog/logging.h>
using namespace std;
int main(int argc, char* argv[])
{
google::InitGoogleLogging(argv[0]);
FLAGS_log_dir = "./logs";
std::string filename = "/home/zhipeng/catkin_ws/src/Kimera-VIO/params/Euroc/PipelineParams.yaml";
cv::FileStorage fs_;
cv::FileStorage *fs = &fs_;
CHECK_NOTNULL(fs)->open(filename, cv::FileStorage::READ);
// fs->open(filename, cv::FileStorage::READ);
std::cout << fs->isOpened() << std::endl;
if (!fs->isOpened())
{
std::cout<< "OK" << std::endl;
}
LOG(INFO) << "Found " << 11 << " cookies";
VLOG(1) << "I’m printed when you run the program with --v=1 or higher";
LOG(INFO) << "Cannot open file: " << '\n';
std::string id = "backend_type";
float a = fs_["backend_type"];
std::cout << a << std::endl;
}
small update, I even copy the reading section in Kimera-VIO-ROS to my code, it won't occur segmentation fault.
#include <opencv2/core.hpp>
#include
using namespace std;
//main.cc
#include <opencv2/core.hpp>
#include <iostream>
#include <string>
#include <glog/logging.h>
#include "yamlPasrser.h"
using namespace std;
int main(int argc, char* argv[])
{
google::InitGoogleLogging(argv[0]);
FLAGS_log_dir = "./logs";
std::string filename = "/home/zhipeng/catkin_ws/src/Kimera-VIO/params/Euroc/PipelineParams.yaml";
YamlParser yaml_parser(filename);
int backend_type;
yaml_parser.getYamlParam("backend_type", &backend_type);
std::cout << std::endl;
}
//yamlPasrser.h
#include <glog/logging.h>
#include <iostream>
#include <opencv2/core/core.hpp>
class YamlParser {
public:
YamlParser(const std::string& filepath) : fs_(), filepath_(filepath) {
openFile(filepath, &fs_);
}
~YamlParser() { closeFile(&fs_); }
template <class T>
void getYamlParam(const std::string& id, T* output) const {
CHECK(!id.empty());
const cv::FileNode& file_handle = fs_[id];
CHECK_NE(file_handle.type(), cv::FileNode::NONE)
<< "Missing parameter: " << id.c_str()
<< " in file: " << filepath_.c_str();
file_handle >> *CHECK_NOTNULL(output);
}
private:
cv::FileStorage fs_;
std::string filepath_;
private:
void openFile(const std::string& filepath, cv::FileStorage* fs) const {
CHECK(!filepath.empty()) << "Empty filepath!";
try {
CHECK_NOTNULL(fs)->open(filepath, cv::FileStorage::READ);
} catch (cv::Exception& e) {
LOG(FATAL) << "Cannot open file: " << filepath << '\n'
<< "OpenCV error code: " << e.msg;
}
LOG_IF(FATAL, !fs->isOpened())
<< "Cannot open file in parseYAML: " << filepath
<< " (remember that the first line should be: %YAML:1.0)";
}
inline void closeFile(cv::FileStorage* fs) const {
CHECK_NOTNULL(fs)->release();
}
};
that's weired. why Kimera-VIO just could not read .yaml file ?
这个问题应该是opencv版本冲突问题,系统里面应该存在两个opencv版本,分别对你的测试程序和ros-node执行ldd命令查看链接的opencv库; ldd install/lib/your_package/your_node | grep opencv ldd your_cpp_test_exe | grep opencv 删除一个确保一致即可; 我这边是保留ros-node的opencv版本,删掉另一个 sudo rm -rf /usr/local/lib/libopencv_* sudo rm -rf /usr/local/include/opencv*