#ifndef SENSOR_SIMULATOR_H #define SENSOR_SIMULATOR_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class SensorSimulator { public: SensorSimulator(ros::NodeHandle &nh) : nh_(nh) { YAML::Node config = YAML::LoadFile(CONFIG_FILE_PATH); // 读取camera参数 fx = config["camera"]["fx"].as(); fy = config["camera"]["fy"].as(); cx = config["camera"]["cx"].as(); cy = config["camera"]["cy"].as(); image_width = config["camera"]["image_width"].as(); image_height = config["camera"]["image_height"].as(); max_depth_dist = config["camera"]["max_depth_dist"].as(); normalize_depth = config["camera"]["normalize_depth"].as(); // 读取lidar参数 vertical_lines = config["lidar"]["vertical_lines"].as(); vertical_angle_start = config["lidar"]["vertical_angle_start"].as(); vertical_angle_end = config["lidar"]["vertical_angle_end"].as(); horizontal_num = config["lidar"]["horizontal_num"].as(); horizontal_resolution = config["lidar"]["horizontal_resolution"].as(); max_lidar_dist = config["lidar"]["max_lidar_dist"].as(); render_lidar = config["render_lidar"].as(); render_depth = config["render_depth"].as(); float depth_fps = config["depth_fps"].as(); float lidar_fps = config["lidar_fps"].as(); std::string ply_file = config["ply_file"].as(); std::string odom_topic = config["odom_topic"].as(); std::string depth_topic = config["depth_topic"].as(); std::string lidar_topic = config["lidar_topic"].as(); float resolution = config["resolution"].as(); int expand_y_times = config["expand_y_times"].as(); int expand_x_times = config["expand_x_times"].as(); pcl::PointCloud::Ptr orig_cloud(new pcl::PointCloud()); printf("1.Reading Point Cloud... \n"); // if (pcl::io::loadPCDFile("/home/lu/用完删除/test/map.pcd", *cloud) == -1) { // PCL_ERROR("Couldn't read PLY file \n"); // return; // } if (pcl::io::loadPLYFile(ply_file, *orig_cloud) == -1) { PCL_ERROR("Couldn't read PLY file \n"); return; } printf("2.Processing... \n"); cloud = pcl::PointCloud::Ptr(new pcl::PointCloud()); *cloud = *orig_cloud; for (int i = 0; i < expand_x_times; ++i) { expand_cloud(cloud, 0); } for (int i = 0; i < expand_y_times; ++i) { expand_cloud(cloud, 1); } octree = pcl::octree::OctreePointCloudSearch::Ptr( new pcl::octree::OctreePointCloudSearch(resolution)); octree->setInputCloud(cloud); octree->addPointsFromInputCloud(); image_pub_ = nh_.advertise(depth_topic, 1); point_cloud_pub_ = nh_.advertise(lidar_topic, 1); odom_sub_ = nh_.subscribe(odom_topic, 1, &SensorSimulator::odomCallback, this); timer_depth_ = nh_.createTimer(ros::Duration(1 / depth_fps), &SensorSimulator::timerDepthCallback, this); timer_lidar_ = nh_.createTimer(ros::Duration(1 / lidar_fps), &SensorSimulator::timerLidarCallback, this); printf("3.Simulation Ready! \n"); ros::spin(); } void odomCallback(const nav_msgs::Odometry::ConstPtr &msg); cv::Mat renderDepthImage(); pcl::PointCloud renderLidarPointcloud(); void timerDepthCallback(const ros::TimerEvent &); void timerLidarCallback(const ros::TimerEvent &); void expand_cloud(pcl::PointCloud::Ptr expanded_cloud, int direction = 0); private: bool render_depth{false}; bool render_lidar{false}; bool odom_init{false}; Eigen::Quaternionf quat; Eigen::Vector3f pos; pcl::PointCloud::Ptr cloud; pcl::octree::OctreePointCloudSearch::Ptr octree; // camera param float fx = 80.0f; // focal length x float fy = 80.0f; // focal length y float cx = 80.0f; // principal point x (image center) float cy = 45.0f; // principal point y (image center) int image_width = 160; int image_height = 90; float max_depth_dist{20}; bool normalize_depth{false}; // lidar param int vertical_lines = 16; // 纵向16线 float vertical_angle_start = -15.0; // 起始垂直角度 float vertical_angle_end = 15.0; // 结束垂直角度 int horizontal_num = 360; // 水平360点 float horizontal_resolution = 1.0; // 水平分辨率为1度 float max_lidar_dist{50}; ros::NodeHandle nh_; ros::Publisher image_pub_, point_cloud_pub_; ros::Subscriber odom_sub_; ros::Timer timer_depth_, timer_lidar_; }; #endif //SENSOR_SIMULATOR_H