rviz学习

今天学习rviz,实验了贺一家博士的《从0开始手写vio》课件中的生成模拟IMU数据这一章节,代码如下:

/*
 * Copyright (c) 2010, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

// %Tag(FULLTEXT)%
// %Tag(INCLUDES)%
#include <ros/ros.h>
#include <visualization_msgs/Marker.h>
#include <geometry_msgs/PoseStamped.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>
#include <fstream>
#include <sys/stat.h>
#include "imu.h"
#include "utilities.h"
// %EndTag(INCLUDES)%

using Point = Eigen::Vector4d;
using Points = std::vector<Point, Eigen::aligned_allocator<Point> >;
using Line = std::pair<Eigen::Vector4d, Eigen::Vector4d>;
using Lines = std::vector<Line, Eigen::aligned_allocator<Line> >;

void CreateHousePointsLines(Points& points, Lines& lines)
{
    std::ifstream f;
    f.open("/home/xueyufei/catkin_ws/src/vio_simulator/house_model/house.txt");

    while(!f.eof())
    {
        std::string s;
        std::getline(f,s);
        if(!s.empty())
        {
            std::stringstream ss;
            ss << s;
            double x,y,z;
            ss >> x;
            ss >> y;
            ss >> z;
            Eigen::Vector4d pt0( x, y, z, 1 );
            ss >> x;
            ss >> y;
            ss >> z;
            Eigen::Vector4d pt1( x, y, z, 1 );

            bool isHistoryPoint = false;
            for (int i = 0; i < points.size(); ++i) {
                Eigen::Vector4d pt = points[i];
                if(pt == pt0)
                {
                    isHistoryPoint = true;
                }
            }
            if(!isHistoryPoint)
                points.push_back(pt0);

            isHistoryPoint = false;
            for (int i = 0; i < points.size(); ++i) {
                Eigen::Vector4d pt = points[i];
                if(pt == pt1)
                {
                    isHistoryPoint = true;
                }
            }
            if(!isHistoryPoint)
                points.push_back(pt1);

            lines.emplace_back(pt0, pt1);   // lines
        }
    }

    // create more 3d points, you can comment this code
    int n = points.size();
    for (int j = 0; j < n; ++j) {
        Eigen::Vector4d p = points[j] + Eigen::Vector4d(0.5, 0.5, -0.5, 0);
        points.push_back(p);
    }
}

visualization_msgs::Marker CreateHousePointMarker(const Points& house_points)
{
    visualization_msgs::Marker marker_points;
    marker_points.header.frame_id = "/my_frame";
    marker_points.header.stamp = ros::Time::now();
    marker_points.ns = "house";
    marker_points.id = 0;
    marker_points.type = visualization_msgs::Marker::POINTS;
    marker_points.action = visualization_msgs::Marker::ADD;
    marker_points.pose.orientation.w =  1.0;

    marker_points.scale.x = 0.1;
    marker_points.scale.y = 0.1;

    marker_points.color.r = 0.0f;
    marker_points.color.g = 1.0f;
    marker_points.color.b = 0.0f;
    marker_points.color.a = 1.0;
    marker_points.lifetime = ros::Duration();

    for (uint32_t i = 0; i < house_points.size(); ++i)
    {
        geometry_msgs::Point p;
        p.x = house_points[i].x();
        p.y = house_points[i].y();
        p.z = house_points[i].z();
        marker_points.points.push_back(p);
    }
    return marker_points;
}

visualization_msgs::Marker CreateHouseLinesMarker(const Lines& house_lines)
{
    visualization_msgs::Marker marker_lines;
    marker_lines.header.frame_id = "/my_frame";
    marker_lines.header.stamp = ros::Time::now();
    marker_lines.ns = "house";
    marker_lines.id = 1;
    marker_lines.type = visualization_msgs::Marker::LINE_LIST;
    marker_lines.action = visualization_msgs::Marker::ADD;
    marker_lines.pose.orientation.w = 1.0;

    marker_lines.scale.x = 0.1;
    marker_lines.scale.y = 0.1;

    marker_lines.color.r = 1.0f;
    marker_lines.color.g = 1.0f;
    marker_lines.color.b = 1.0f;
    marker_lines.color.a = 1.0;
    marker_lines.lifetime = ros::Duration();

    for (uint32_t i = 0; i < house_lines.size(); ++i)
    {
        geometry_msgs::Point p0;
        p0.x = house_lines[i].first.x();
        p0.y = house_lines[i].first.y();
        p0.z = house_lines[i].first.z();
        marker_lines.points.push_back(p0);

        geometry_msgs::Point p1;
        p1.x = house_lines[i].second.x();
        p1.y = house_lines[i].second.y();
        p1.z = house_lines[i].second.z();
        marker_lines.points.push_back(p1);
    }
    return marker_lines;
}

visualization_msgs::Marker CreateTrajMarker()
{
    visualization_msgs::Marker traj_marker;
    traj_marker.header.frame_id = "/my_frame";
    traj_marker.header.stamp = ros::Time::now();
    traj_marker.ns = "house";
    traj_marker.id = 2;
    traj_marker.type =  visualization_msgs::Marker::LINE_STRIP;
    traj_marker.action =  visualization_msgs::Marker::ADD;
    traj_marker.pose.orientation.w = 1.0;

    traj_marker.scale.x = 0.1;
    traj_marker.scale.y = 0.1;

    traj_marker.color.r = 1.0f;
    traj_marker.color.g = 0.0f;
    traj_marker.color.b = 0.0f;
    traj_marker.color.a = 1.0;
    traj_marker.lifetime = ros::Duration();
    return traj_marker;
}

MotionData GenerateImuData(IMU& imuGen, float t)
{
    MotionData data = imuGen.MotionModel(t);
    MotionData data_noise = data;
    imuGen.addIMUnoise(data_noise);
    return data_noise;
}

Eigen::Vector2d p2c(const Eigen::Vector3d& pos, Param param)
{
    Eigen::Matrix3d cam;
    cam << param.fx, 0, param.cx,
        0, param.fy, param.cy, 
        0, 0, 1;
    Eigen::Vector3d uvz = cam * pos;
    Eigen::Vector2d uv;
    uv.x() = uvz.x() / uvz.z();
    uv.y() = uvz.y() / uvz.z();
    return uv;
}

std::vector<Eigen::Vector2d> GenerateImageFeatures(MotionData& imu_data, Param params, Points house_points)
{
    MotionData cam;
    cam.timestamp = imu_data.timestamp;
    cam.Rwb = imu_data.Rwb * params.R_bc;
    cam.twb = imu_data.twb + imu_data.Rwb * params.t_bc; //  Tcw = Twb * Tbc ,  t = Rwb * tbc + twb
    Eigen::Matrix4d Twc = Eigen::Matrix4d::Identity();
    Twc.block(0, 0, 3, 3) = cam.Rwb;
    Twc.block(0, 3, 3, 1) = cam.twb;
    std::vector<Eigen::Vector2d> features_cam;
    for (int i = 0; i < house_points.size(); ++i)
    {
        Eigen::Vector4d pw = house_points[i]; 
        Eigen::Vector4d pc1 = Twc.inverse() * pw; // T_wc.inverse() * Pw  -- > point in cam frame
        if (pc1(2) < 0)
            continue;

        Eigen::Vector2d uv = p2c(pc1.topLeftCorner(3, 1), params);
        features_cam.push_back(uv);
    }
    return features_cam;
}

std::vector<std::pair<Eigen::Vector2d, Eigen::Vector2d>> GenerateImageHouse(MotionData& imu_data, Param params, Lines house_lines)
{
    MotionData cam;
    cam.timestamp = imu_data.timestamp;
    cam.Rwb = imu_data.Rwb * params.R_bc;
    cam.twb = imu_data.twb + imu_data.Rwb * params.t_bc; //  Tcw = Twb * Tbc ,  t = Rwb * tbc + twb
    Eigen::Matrix4d Twc = Eigen::Matrix4d::Identity();
    Twc.block(0, 0, 3, 3) = cam.Rwb;
    Twc.block(0, 3, 3, 1) = cam.twb;
    std::vector<std::pair<Eigen::Vector2d, Eigen::Vector2d>> lines_cam; 
    for (int i = 0; i < house_lines.size(); ++i)
    {
        Line line = house_lines[i]; 
        Eigen::Vector4d pc0 = Twc.inverse() * line.first; // T_wc.inverse() * Pw  -- > point in cam frame
        Eigen::Vector4d pc1 = Twc.inverse() * line.second; // T_wc.inverse() * Pw  -- > point in cam frame
        if (pc0(2) < 0 && pc1(2) < 0)
            continue;

        Eigen::Vector2d uv0 = p2c(pc0.topLeftCorner(3, 1), params);
        Eigen::Vector2d uv1 = p2c(pc1.topLeftCorner(3, 1), params);
        lines_cam.emplace_back(uv0, uv1);
    }
    return lines_cam;
}

int main( int argc, char** argv )
{
  ros::init(argc, argv, "vio_simulator_xyf");
  ros::NodeHandle n;
  ros::Publisher marker_pub = n.advertise<visualization_msgs::Marker>("visualization_marker", 10);
  ros::Publisher pose_pub = n.advertise<geometry_msgs::PoseStamped>("pose_marker", 10);
  
  image_transport::ImageTransport it(n);
  image_transport::Publisher cam_pub = it.advertise("camera/image", 1);
  ros::Rate r(30);

  Points house_points;
  Lines house_lines;
  CreateHousePointsLines(house_points, house_lines);

  visualization_msgs::Marker traj_marker = CreateTrajMarker();
  visualization_msgs::Marker marker_points = CreateHousePointMarker(house_points);
  visualization_msgs::Marker marker_lines = CreateHouseLinesMarker(house_lines);

  Param params;
  IMU imuGen(params);
  float t = params.t_start;

  while (ros::ok())
  {
    while (marker_pub.getNumSubscribers() < 1)
    {
      if (!ros::ok())
      {
        return 0;
      }
      ROS_WARN_ONCE("Please create a subscriber to the marker");
      sleep(1);
    }
    ROS_WARN_ONCE("succeed!");
    marker_pub.publish(marker_points);
    marker_pub.publish(marker_lines);

    MotionData imu_data = GenerateImuData(imuGen, t);
    Eigen::Quaterniond q(imu_data.Rwb);

    geometry_msgs::PoseStamped po;
    po.pose.position.x = imu_data.twb.x();
    po.pose.position.y = imu_data.twb.y();
    po.pose.position.z = imu_data.twb.z();
    po.pose.orientation.x = q.x();
    po.pose.orientation.y = q.y();
    po.pose.orientation.z = q.z();
    po.pose.orientation.w = q.w();
    po.header.frame_id= "/my_frame";
    pose_pub.publish(po);

    geometry_msgs::Point traj_point;
    traj_point.x = imu_data.twb.x();
    traj_point.y = imu_data.twb.y();
    traj_point.z = imu_data.twb.z();
    traj_marker.points.push_back(traj_point);
    marker_pub.publish(traj_marker);

    std::vector<Eigen::Vector2d>  features_cam = GenerateImageFeatures(imu_data, params, house_points);
    std::vector<std::pair<Eigen::Vector2d, Eigen::Vector2d>> line2ds = GenerateImageHouse(imu_data, params, house_lines);
    cv::Mat image(params.image_h, params.image_w,  CV_8UC3, cv::Scalar(0, 0, 0));
    for(Eigen::Vector2d feature : features_cam) 
    {
        cv::circle(image, cv::Point(feature.x(), feature.y()), 1.0, cv::Scalar(0, 255, 255), 2);
    }
    for(auto line2d : line2ds) 
    {
        cv::line(image, cv::Point(line2d.first.x(), line2d.first.y()), cv::Point(line2d.second.x(), line2d.second.y()), cv::Scalar(255, 255, 255), 2);
    }
    sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg();
    cam_pub.publish(msg);

    t += 1.0 / params.imu_frequency;
    r.sleep();
  }
}

效果如下

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神气爱哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值