当前位置:   article > 正文

实现激光塔和雷达的轨迹对比

实现激光塔和雷达的轨迹对比

一、录制bag包

1、使用FAST-LIO2运行mid360

安装ROS驱动,需要把livox_ros_driver2放到已有的ros工程下

(1)下载fast-lio2

(2)运行fast_lio2_ws和livox_mid360_driver_ws

  1. roslaunch fast_lio mapping_avia.launch
  2. roslaunch livox_ros_driver2 msg_MID360.launch

2、运行px4_command

  1. roscore
  2. source devel/setup.bash
  3. rosrun px4_command pub_vive_pose
  4. source devel/setup.bash
  5. rosrun px4_command px4_pos_estimator

 3、录制bag包

终端执行:rosbag record -o(包含时间) xxx.bag 话题名1 话题名2 …如

rosbag record -o zh.bag /mavros/vision_pose/pose /Odometry 

使用ctrl+c终止录制,不然会生存.bag.active后缀的文件,需要进行转换

转换方法:

  1. ①切换到xxx.bag.active文件所在的目录下;
  2. ②命令行输入rosbag reindex xxx.bag.active;
  3. ③输入rosbag fix xxx.bag.active result.bag;

二、安装和使用rpg_trajectory_evaluation

1、编译

  1. mkdir catkin_ws
  2. cd catkin_ws
  3. mkdir src
  4. cd src
  5. git clone https://github.com/uzh-rpg/rpg_trajectory_evaluation.git
  6. git clone https://github.com/catkin/catkin_simple.git
  7. cd ..
  8. catkin_make

2、安装依赖库

  1. pip install numpy
  2. pip install matplotlib
  3. pip install colorama
  4. pip install ruamel.yaml
  5. sudo apt install texlive-fonts-recommended texlive-fonts-extra
  6. sudo apt install dvipng

3、将rosbag转换为需要的文件,通过bag_to_pose.py

  1. python3 /home/zhong/projects/rpg/src/rpg_trajectory_evaluation/scripts/dataset_tools/bag_to_pose.py /home/zhong/Bag/zh.bag --msg_type PoseStamped --output stamped_traj_estimate.txt /mavros/vision_pose/pose
  2. python3 /home/zhong/projects/rpg/src/rpg_trajectory_evaluation/scripts/dataset_tools/bag_to_pose.py /home/zhong/Bag/zh.bag --msg_type PoseWithCovarianceStamped --output stamped_groundtruth.txt /Odometry
  3. 语句:pythonx(对应的版本)
  4. 因为是对比不同话题的轨迹,所以要生成两个txt文件

4、使用analyze_trajectory_single.py进行分析

python3 scripts/analyze_trajectory_single.py /home/zhong/xxx(包含两个txt文件的文件夹名)

三、在rviz中可视化对比轨迹

1、启动rviz:

rviz

2、播放bag包:

指令:rosbag play -loop(循环播放) xxx.bag;

3、在rviz中订阅相应的话题

4、修改参考系:在如图位置可以查看





四、ROS里程计消息nav_msgs/Odometry的可视化方法

此处参照:

ROS里程计消息nav_msgs/Odometry的可视化方法_nav_msgs::odometry_Studying Cui的博客-CSDN博客

可视化的方法为:

①在一个节点中订阅发布的里程计话题消息nav_msgs/Odometry

②创建geometry_msgs::PoseStamped对象接收里程计的位姿

③创建nav_msgs/Path对象作为容器,将赋值后的对象push_back进nav_msgs/Path中并发布

然后即可在rviz中订阅包含nav_msgs/Path的话题并可视化轨迹

1.新建ROS工作空间

  1. mkdir -p path_ws/src
  2. cd path_ws
  3. catkin_make
  4. cd src
  5. catkin_create_pkg path_3d roscpp rospy std_msgs nav_msgs geometry_msgs

2.在path_3d/src中编写消息收发节点文件path_3d.cpp

  1. #include <ros/ros.h>
  2. #include <nav_msgs/Path.h>
  3. #include <std_msgs/String.h>
  4. #include <nav_msgs/Odometry.h>
  5. #include <geometry_msgs/PoseStamped.h>
  6. #include <tf/transform_broadcaster.h>
  7. #include <tf/tf.h>
  8. nav_msgs::Path path;
  9. ros::Publisher path_pub;
  10. void pathCallback(const nav_msgs::Odometry::ConstPtr& odom_3d)
  11. {
  12. geometry_msgs::PoseStamped position_3d;
  13. position_3d.pose.position.x = odom_3d->pose.pose.position.x;
  14. position_3d.pose.position.y = odom_3d->pose.pose.position.y;
  15. position_3d.pose.position.z = odom_3d->pose.pose.position.z;
  16. position_3d.pose.orientation = odom_3d->pose.pose.orientation;
  17. position_3d.header.stamp = odom_3d->header.stamp;
  18. position_3d.header.frame_id = "map";
  19. path.poses.push_back(position_3d);
  20. path.header.stamp = position_3d.header.stamp;
  21. path.header.frame_id = "map";
  22. path_pub.publish(path);
  23. std::cout << odom_3d -> header.stamp << ' ' << odom_3d->pose.pose.position.x << ' ' << odom_3d->pose.pose.position.y << ' ' << odom_3d->pose.pose.position.z << std::endl;
  24. }
  25. int main (int argc, char **argv)
  26. {
  27. ros::init (argc, argv, "showpath");
  28. ros::NodeHandle ph;
  29. path_pub = ph.advertise<nav_msgs::Path>("odom3d_path", 10, true);
  30. ros::Subscriber odomSub = ph.subscribe<nav_msgs::Odometry>("/odometry_3d", 10, pathCallback); //订阅里程计话题信息,其中"/odometry_3d"是自己发布的里程计话题名,别忘了修改
  31. ros::Rate loop_rate(1000);
  32. while(ros::ok())
  33. {
  34. ros::spinOnce();
  35. loop_rate.sleep();
  36. }
  37. return 0;
  38. }

3.path_3d文件夹目录中的CMakeLists.txt如下

  1. cmake_minimum_required(VERSION 2.8.3)
  2. project(path_3d)
  3. ## Compile as C++11, supported in ROS Kinetic and newer
  4. # add_compile_options(-std=c++11)
  5. find_package(catkin REQUIRED COMPONENTS
  6. geometry_msgs
  7. roscpp
  8. rospy
  9. std_msgs
  10. message_generation
  11. )
  12. ## Generate added messages and services with any dependencies listed here
  13. generate_messages(
  14. DEPENDENCIES
  15. geometry_msgs std_msgs
  16. )
  17. catkin_package(
  18. INCLUDE_DIRS include
  19. LIBRARIES path_3d
  20. CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs
  21. DEPENDS system_lib
  22. )
  23. include_directories(
  24. include
  25. ${catkin_INCLUDE_DIRS}
  26. )
  27. add_executable(path_3d src/path_3d.cpp) #${PROJECT_NAME}_node
  28. target_link_libraries(path_3d ${catkin_LIBRARIES}) # ${PROJECT_NAME}_node
  29. add_dependencies(path_3d beginner_tutorials_generate_messages_cpp) #path_3d_node

4.在工作空间中编译功能包

  1. // 打开命令行
  2. // 进入工作空间最上层目录
  3. cd path_ws
  4. // 执行一下 source 命令
  5. source devel/setup.bash
  6. // 编译工作空间下的所有功能包
  7. catkin_make
  8. // 单独编译工作空间下的 path_3d 功能包
  9. catkin_make -DCATKIN_WHITELIST_PACKAGES="path_3d"

四、对数据进行补偿

1、对path_3d.cpp文件进行修改
(1)先补偿z轴方向的差值,然后在二维中进行向量的旋转
(2)通过四元数进行旋转:

此处参照:

ROS TF2 中的 四元数 基础部分 - 古月居

a、将一个姿态(用四元数表示) 做一个 旋转(用四元数表示) ,只需要将 姿态的四元数 乘以旋转的四元数,例子:
  1. #include <tf2_geometry_msgs/tf2_geometry_msgs.h>
  2. //q_orig 是原姿态转换的tf的四元数
  3. //q_rot 旋转四元数
  4. //q_new 旋转后的姿态四元数
  5. tf2::Quaternion q_orig, q_rot, q_new;
  6. // commanded_pose.pose.orientation 这个比如说 是 订阅的别的节点的topic 是一个 姿态的 msg 四元数
  7. //通过tf2::convert() 转换成 tf 的四元数
  8. tf2::convert(commanded_pose.pose.orientation , q_orig);
  9. // 设置 绕 x 轴 旋转180
  10. double r=3.14159, p=0, y=0;
  11. q_rot.setRPY(r, p, y);//求得 tf 的旋转四元数
  12. q_new = q_rot*q_orig; // 通过 姿态的四元数 乘以旋转的四元数 即为 旋转 后的 四元数
  13. q_new.normalize(); // 归一化
  14. // 将 旋转后的 tf 四元数 转换 为 msg 四元数
  15. tf2::convert(q_new, commanded_pose.pose.orientation);
b、四元数转置:将w参数加上一个负号
c、求两个姿态(四元数)的旋转角

假如在一个坐标系下有两个 姿态 用四元数 表示的q_1和q_2,那如何求这两个姿态的旋转四元数q_r呢。

q_2 = q_r*q_1

可以类似于求解矩阵方程来求解q_r。颠倒q_1并将两边右乘。同样,乘法的顺序很重要:

q_r = q_2*q_1_inverse

例子:

  1. q1_inv[0] = prev_pose.pose.orientation.x
  2. q1_inv[1] = prev_pose.pose.orientation.y
  3. q1_inv[2] = prev_pose.pose.orientation.z
  4. q1_inv[3] = -prev_pose.pose.orientation.w //注意这个负号
  5. q2[0] = current_pose.pose.orientation.x
  6. q2[1] = current_pose.pose.orientation.y
  7. q2[2] = current_pose.pose.orientation.z
  8. q2[3] = current_pose.pose.orientation.w
  9. qr = tf.transformations.quaternion_multiply(q2, q1_inv)



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/687916
推荐阅读
相关标签
  

闽ICP备14008679号