赞
踩
安装ROS驱动,需要把livox_ros_driver2放到已有的ros工程下
(1)下载fast-lio2
(2)运行fast_lio2_ws和livox_mid360_driver_ws
- roslaunch fast_lio mapping_avia.launch
- roslaunch livox_ros_driver2 msg_MID360.launch
- roscore
-
- source devel/setup.bash
- rosrun px4_command pub_vive_pose
-
- source devel/setup.bash
- 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后缀的文件,需要进行转换
转换方法:
- ①切换到xxx.bag.active文件所在的目录下;
- ②命令行输入rosbag reindex xxx.bag.active;
- ③输入rosbag fix xxx.bag.active result.bag;
- mkdir catkin_ws
- cd catkin_ws
- mkdir src
- cd src
- git clone https://github.com/uzh-rpg/rpg_trajectory_evaluation.git
- git clone https://github.com/catkin/catkin_simple.git
- cd ..
- catkin_make
- pip install numpy
- pip install matplotlib
- pip install colorama
- pip install ruamel.yaml
- sudo apt install texlive-fonts-recommended texlive-fonts-extra
- sudo apt install dvipng
bag_to_pose.py
- 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
-
- 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
-
- 语句:pythonx(对应的版本)
- 因为是对比不同话题的轨迹,所以要生成两个txt文件
python3 scripts/analyze_trajectory_single.py /home/zhong/xxx(包含两个txt文件的文件夹名)
rviz
指令:rosbag play -loop(循环播放) xxx.bag;
此处参照:
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的话题并可视化轨迹
- mkdir -p path_ws/src
- cd path_ws
- catkin_make
- cd src
- catkin_create_pkg path_3d roscpp rospy std_msgs nav_msgs geometry_msgs
2.在path_3d/src中编写消息收发节点文件path_3d.cpp
- #include <ros/ros.h>
- #include <nav_msgs/Path.h>
- #include <std_msgs/String.h>
- #include <nav_msgs/Odometry.h>
- #include <geometry_msgs/PoseStamped.h>
- #include <tf/transform_broadcaster.h>
- #include <tf/tf.h>
-
-
- nav_msgs::Path path;
- ros::Publisher path_pub;
-
-
- void pathCallback(const nav_msgs::Odometry::ConstPtr& odom_3d)
- {
- geometry_msgs::PoseStamped position_3d;
- position_3d.pose.position.x = odom_3d->pose.pose.position.x;
- position_3d.pose.position.y = odom_3d->pose.pose.position.y;
- position_3d.pose.position.z = odom_3d->pose.pose.position.z;
- position_3d.pose.orientation = odom_3d->pose.pose.orientation;
- position_3d.header.stamp = odom_3d->header.stamp;
- position_3d.header.frame_id = "map";
-
-
- path.poses.push_back(position_3d);
- path.header.stamp = position_3d.header.stamp;
- path.header.frame_id = "map";
- path_pub.publish(path);
-
- 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;
- }
-
-
- int main (int argc, char **argv)
- {
- ros::init (argc, argv, "showpath");
- ros::NodeHandle ph;
-
-
- path_pub = ph.advertise<nav_msgs::Path>("odom3d_path", 10, true);
- ros::Subscriber odomSub = ph.subscribe<nav_msgs::Odometry>("/odometry_3d", 10, pathCallback); //订阅里程计话题信息,其中"/odometry_3d"是自己发布的里程计话题名,别忘了修改
-
- ros::Rate loop_rate(1000);
- while(ros::ok())
- {
- ros::spinOnce();
- loop_rate.sleep();
- }
- return 0;
- }
- cmake_minimum_required(VERSION 2.8.3)
- project(path_3d)
-
- ## Compile as C++11, supported in ROS Kinetic and newer
- # add_compile_options(-std=c++11)
-
- find_package(catkin REQUIRED COMPONENTS
- geometry_msgs
- roscpp
- rospy
- std_msgs
- message_generation
- )
-
- ## Generate added messages and services with any dependencies listed here
- generate_messages(
- DEPENDENCIES
- geometry_msgs std_msgs
- )
- catkin_package(
- INCLUDE_DIRS include
- LIBRARIES path_3d
- CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs
- DEPENDS system_lib
- )
-
- include_directories(
- include
- ${catkin_INCLUDE_DIRS}
- )
-
- add_executable(path_3d src/path_3d.cpp) #${PROJECT_NAME}_node
- target_link_libraries(path_3d ${catkin_LIBRARIES}) # ${PROJECT_NAME}_node
- add_dependencies(path_3d beginner_tutorials_generate_messages_cpp) #path_3d_node
- // 打开命令行
- // 进入工作空间最上层目录
- cd path_ws
- // 执行一下 source 命令
- source devel/setup.bash
- // 编译工作空间下的所有功能包
- catkin_make
- // 单独编译工作空间下的 path_3d 功能包
- catkin_make -DCATKIN_WHITELIST_PACKAGES="path_3d"
此处参照:
- #include <tf2_geometry_msgs/tf2_geometry_msgs.h>
- //q_orig 是原姿态转换的tf的四元数
- //q_rot 旋转四元数
- //q_new 旋转后的姿态四元数
- tf2::Quaternion q_orig, q_rot, q_new;
-
- // commanded_pose.pose.orientation 这个比如说 是 订阅的别的节点的topic 是一个 姿态的 msg 四元数
- //通过tf2::convert() 转换成 tf 的四元数
- tf2::convert(commanded_pose.pose.orientation , q_orig);
-
- // 设置 绕 x 轴 旋转180度
- double r=3.14159, p=0, y=0;
- q_rot.setRPY(r, p, y);//求得 tf 的旋转四元数
-
- q_new = q_rot*q_orig; // 通过 姿态的四元数 乘以旋转的四元数 即为 旋转 后的 四元数
- q_new.normalize(); // 归一化
-
- // 将 旋转后的 tf 四元数 转换 为 msg 四元数
- tf2::convert(q_new, commanded_pose.pose.orientation);
假如在一个坐标系下有两个 姿态 用四元数 表示的q_1和q_2,那如何求这两个姿态的旋转四元数q_r呢。
q_2 = q_r*q_1
可以类似于求解矩阵方程来求解q_r。颠倒q_1并将两边右乘。同样,乘法的顺序很重要:
q_r = q_2*q_1_inverse
例子:
- q1_inv[0] = prev_pose.pose.orientation.x
- q1_inv[1] = prev_pose.pose.orientation.y
- q1_inv[2] = prev_pose.pose.orientation.z
- q1_inv[3] = -prev_pose.pose.orientation.w //注意这个负号
-
- q2[0] = current_pose.pose.orientation.x
- q2[1] = current_pose.pose.orientation.y
- q2[2] = current_pose.pose.orientation.z
- q2[3] = current_pose.pose.orientation.w
-
- qr = tf.transformations.quaternion_multiply(q2, q1_inv)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。