// Publish the surrounding point cloud map based on the drone's position for visualization. #include #include #include #include #include #include #include #include #include #include #include "visualization_msgs/Marker.h" namespace map_visual { pcl::PointCloud::Ptr cloud(new pcl::PointCloud); void pcl_input() { std::string cfg_path = getenv("FLIGHTMARE_PATH") + std::string("/flightlib/configs/quadrotor_ros.yaml"); YAML::Node cfg_ = YAML::LoadFile(cfg_path); std::string ply_path_ = getenv("FLIGHTMARE_PATH") + cfg_["ply_path"].as() + "pointcloud-0.ply"; pcl::io::loadPLYFile(ply_path_, *cloud); std::cout << "size of pointcloud: " << cloud->points.size() << std::endl; } void odom_cb(const nav_msgs::Odometry::ConstPtr odom_msg, ros::Publisher* local_map_pub, ros::Publisher* mesh_pub, tf::TransformBroadcaster* uav_tf_br) { // 1. publish tf tf::Transform transform; transform.setOrigin(tf::Vector3(odom_msg->pose.pose.position.x, odom_msg->pose.pose.position.y, odom_msg->pose.pose.position.z)); tf::Quaternion q(0, 0, 0, 1); // tf::Quaternion q(odom_msg->pose.pose.orientation.x, odom_msg->pose.pose.orientation.y, // odom_msg->pose.pose.orientation.z, odom_msg->pose.pose.orientation.w); transform.setRotation(q); uav_tf_br->sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", "uav")); // 2. publish map Eigen::Vector3f pose_cur(odom_msg->pose.pose.position.x, odom_msg->pose.pose.position.y, odom_msg->pose.pose.position.z); Eigen::Vector3f local_map_half_size(8, 8, 1); pcl::PointCloud::Ptr local_map(new pcl::PointCloud); for (auto& x : cloud->points) { if (x.z > pose_cur(2) - 6 && x.z < pose_cur(2) + local_map_half_size(2) && x.x > pose_cur(0) - local_map_half_size(0) && x.x < pose_cur(0) + local_map_half_size(0) && x.y > pose_cur(1) - local_map_half_size(1) && x.y < pose_cur(1) + local_map_half_size(1)) { local_map->points.push_back(x); } } pcl_conversions::toPCL(ros::Time::now(), local_map->header.stamp); local_map->header.frame_id = "world"; local_map_pub->publish(local_map); // 3. publish UAV model std::string mesh_resource = std::string("file://") + getenv("FLIGHTMARE_PATH") + std::string("/flightlib/src/ros_nodes/model/uav.dae"); visualization_msgs::Marker meshROS; meshROS.header.frame_id = "world"; meshROS.header.stamp = ros::Time::now(); meshROS.ns = "mesh"; meshROS.id = 0; meshROS.type = visualization_msgs::Marker::MESH_RESOURCE; meshROS.action = visualization_msgs::Marker::ADD; meshROS.pose.position.x = odom_msg->pose.pose.position.x - 0.2; meshROS.pose.position.y = odom_msg->pose.pose.position.y; meshROS.pose.position.z = odom_msg->pose.pose.position.z; meshROS.pose.orientation.w = odom_msg->pose.pose.orientation.w; meshROS.pose.orientation.x = odom_msg->pose.pose.orientation.x; meshROS.pose.orientation.y = odom_msg->pose.pose.orientation.y; meshROS.pose.orientation.z = odom_msg->pose.pose.orientation.z; float scale = 2; meshROS.scale.x = scale; meshROS.scale.y = scale; meshROS.scale.z = scale; meshROS.color.a = 1; meshROS.color.r = 1; meshROS.color.g = 1; meshROS.color.b = 1; meshROS.mesh_resource = mesh_resource; meshROS.mesh_use_embedded_materials = true; mesh_pub->publish(meshROS); } } // namespace map_visual using namespace map_visual; int main(int argc, char** argv) { pcl_input(); ros::init(argc, argv, "map_visual"); ros::NodeHandle nh; tf::TransformBroadcaster uav_tf_br; ros::Publisher local_map_pub = nh.advertise>("/local_map", 1); ros::Publisher mesh_pub = nh.advertise("/uav_mesh", 1); ros::Subscriber odom_sub = nh.subscribe("/juliett/ground_truth/odom", 1, boost::bind(&odom_cb, _1, &local_map_pub, &mesh_pub, &uav_tf_br)); std::cout << "Map visual node OK!" << std::endl; ros::spin(); }