ROS常用组件

33 篇文章 0 订阅
27 篇文章 0 订阅

一、tf坐标变换

1.静态坐标变换

功能实现:发布方:发布世界坐标系和子坐标系之间的关系,以及转换的方法
                  订阅方:订阅接受发布方的消息,利用订阅到的方法转化坐标

第一步:创建功能包

catkin_create_pkg tf01_static roscpp rospy std_msgs tf2 tf2_ros tf2_geometry_msgs geometry_msgs

第二步:CMakelist文件编写

cmake_minimum_required(VERSION 3.0.2)
project(tf01_static)

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  tf2
  tf2_geometry_msgs
  tf2_ros
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES tf01_static
#  CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs tf2 tf2_geometry_msgs tf2_ros
#  DEPENDS system_lib
)

include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

add_executable(tf01_static src/tf01_static.cpp)

add_dependencies(tf01_static ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(tf01_static
  ${catkin_LIBRARIES}
)

第三步:编写cpp文件

publish.cpp

# include "ros/ros.h"
# include "tf2_ros/static_transform_broadcaster.h"//创建静态坐标转换广播器
# include "geometry_msgs/TransformStamped.h"//创建坐标系信息
# include "tf2/LinearMath/Quaternion.h" //设置四元数

int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "");

    ros::init(argc, argv, "tf2_static");

    ros::NodeHandle n;
    //创建静态坐标转换广播器
    tf2_ros::StaticTransformBroadcaster broadcaster;
    //创建坐标系信息
    geometry_msgs::TransformStamped ts;
    //设置头信息
    ts.header.seq = 100;//头信息
    ts.header.stamp = ros::Time::now();//时间戳
    ts.header.frame_id = "base_link";//被参考的坐标系
    //设置子级坐标系
    ts.child_frame_id = "laser";
    //设置子级相对于父级的偏移量
    ts.transform.translation.x = 0.2;
    ts.transform.translation.y = 0.0;
    ts.transform.translation.z = 0.5;
    //设置四元数
    tf2::Quaternion qtn;//利用欧拉角转换
    qtn.setRPY(0,0,0);//设置的欧拉角,即相对的偏移俯仰和翻滚,数值都为弧度值
    //将欧拉角转化为四元数
    ts.transform.rotation.x = qtn.getX();
    ts.transform.rotation.y = qtn.getY();
    ts.transform.rotation.z = qtn.getZ();
    ts.transform.rotation.w = qtn.getW();
    //广播器发布坐标信息
    broadcaster.sendTransform(ts);
    ros::spin();
    return 0;
}

sub.cpp

# include "ros/ros.h"
# include "tf2_ros/transform_listener.h"//创建订阅对象
# include "tf2_ros/buffer.h"//订阅的数据实现缓存
# include "geometry_msgs/PointStamped.h"//创建一个坐标点数据
# include "tf2_geometry_msgs/tf2_geometry_msgs.h"//转换过程中用到自己封装的消息

int main (int argc, char* argv[])
{
    setlocale(LC_ALL, "");
    ros::init(argc, argv, "tf01_static_sub");
    ros::NodeHandle n;
    //创建订阅对象
    //创建一个buffer缓存
    tf2_ros::Buffer buffer;
    //创建监听对象
    tf2_ros::TransformListener listener(buffer);
    //创建一个坐标点数据
    geometry_msgs::PointStamped ps;
    ps.header.frame_id = "laser";
    ps.header.stamp = ros::Time::now();
    ps.point.x = 2.0;
    ps.point.y = 3.0;
    ps.point.z = 5.0;
    //添加休眠,防止初始时刻出现异常,比如发布方坐标关系还没有准备好
    //ros::Duration(2).sleep();//这个的代码功能和下面的try的功能是一样的
    //执行转换算法
    ros::Rate rate(10);
    while (ros::ok())
    {
        try//检测是否订阅到话题消息,防止发布方的坐标关系还没有准备好
        {
            //核心代码转化
            geometry_msgs::PointStamped ps_out;
            //buffer.transform(ps,"base_link")//实现坐标点的转化,第一个参数是原始坐标系,第二个参数是相对与哪一个坐标实现转换,转化后的坐标给ps_out
            ps_out = buffer.transform(ps,"base_link");
            ROS_INFO("转换后的坐标值是:(%.2f,%.2f,%.2f),参考坐标系:%s",ps_out.point.x,ps_out.point.y,ps_out.point.z,ps_out.header.frame_id.c_str());
            rate.sleep();
            ros::spinOnce();
        }
        catch(const std::exception& e)
        {
            ROS_INFO("Error:%s",e.what());
        }
    }
    return 0;
}

第四步:打开rviz运行

2.动态坐标变换

功能实现:发布方:发布世界坐标系和小乌龟动态坐标系之间的关系,以及转换方法
                  订阅方:订阅接受发布方的消息,已知一个相对于小乌龟坐标系的坐标,转换为相对于世界坐标系的坐标

第一步:第一步:创建功能包

catkin_create_pkg geometry_msgs roscpp rospy std_msgs tf2 tf2_geometry_msgs tf2_ros turtlesim

第二步:CMakelist文件编写

cmake_minimum_required(VERSION 3.0.2)
project(tf01_dynamic)

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  tf2
  tf2_geometry_msgs
  tf2_ros
  turtlesim
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES tf01_dynamic
#  CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs tf2 tf2_geometry_msgs tf2_ros turtlesim
#  DEPENDS system_lib
)

include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

add_executable(tf01_dynamic_pub src/tf01_dynamic_pub.cpp)
add_executable(tf01_dynamic_sub src/tf01_dynamic_sub.cpp)

add_dependencies(tf01_dynamic_pub ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(tf01_dynamic_sub ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(tf01_dynamic_pub
  ${catkin_LIBRARIES}
)
target_link_libraries(tf01_dynamic_sub
  ${catkin_LIBRARIES}
)

第三步:编写发布者

# include "ros/ros.h"
# include "turtlesim/Pose.h"//乌龟的位子信息
# include "tf2_ros/transform_broadcaster.h"//发布坐标关系
# include "geometry_msgs/TransformStamped.h"//发布的坐标信息类型
# include "tf2/LinearMath/Quaternion.h"//欧拉角

void callback(const turtlesim::Pose::ConstPtr& pose)
{
    //获取位姿并发布
    //创建TF发布对象
    static tf2_ros::TransformBroadcaster pub;
    //组织发布数据
    geometry_msgs::TransformStamped ts;
    ts.header.frame_id = "world";
    ts.header.stamp = ros::Time::now();
    ts.child_frame_id = "turtle1";
    //坐标偏移量设置
    ts.transform.translation.x = pose->x;
    ts.transform.translation.y = pose->y;
    ts.transform.translation.z = 0;
    //坐标系四元数
    tf2::Quaternion qtn;
    qtn.setRPY(0,0,pose->theta);//乌龟的欧拉角
    ts.transform.rotation.x = qtn.getX();
    ts.transform.rotation.y = qtn.getY();
    ts.transform.rotation.z = qtn.getZ();
    ts.transform.rotation.w = qtn.getW();
    //发布
    pub.sendTransform(ts);
}

int main (int argc, char* argv[])
{
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"dynamic_pub");
    ros::NodeHandle n;
    //创建订阅对象,订阅乌龟位姿话题
    ros::Subscriber sub = n.subscribe("/turtle1/pose",100,callback);
    ros::spin();
    return 0;
}

第四步:编写订阅者

# include "ros/ros.h"
# include "tf2_ros/transform_listener.h"
# include "tf2_ros/buffer.h"
# include "geometry_msgs/PointStamped.h"
# include "tf2_geometry_msgs/tf2_geometry_msgs.h"//坐标点转换需要的头文件

int main (int argc, char* argv[])
{
    setlocale(LC_ALL, "");
    ros::init(argc, argv, "tf01_static_sub");
    ros::NodeHandle n;
    //创建订阅对象
    //创建一个buffer缓存
    tf2_ros::Buffer buffer;
    //创建监听对象
    tf2_ros::TransformListener listener(buffer);
    //创建一个坐标点数据
    geometry_msgs::PointStamped ps;
    ps.header.frame_id = "turtle1";
    ps.header.stamp = ros::Time(0.0);//动态坐标变换不能用ros::Time::now()
    ps.point.x = 2.0;
    ps.point.y = 3.0;
    ps.point.z = 5.0;
    //执行转换算法
    ros::Rate rate(10);
    while (ros::ok)
    {
        try//检测是否订阅到话题消息
        {
            //核心代码转化
            geometry_msgs::PointStamped ps_out;
            ps_out = buffer.transform(ps,"world");
            ROS_INFO("转换后的坐标值是:(%.2f,%.2f,%.2f),参考坐标系:%s",ps_out.point.x,ps_out.point.y,ps_out.point.z,ps_out.header.frame_id.c_str());
            rate.sleep();
            ros::spinOnce();
        }
        catch(const std::exception& e)
        {
            ROS_INFO("Error:%s",e.what());
        }
    }
    return 0;
}

3.多坐标变换

功能实现:launch文件:发布son1坐标系和son2坐标系相对于世界坐标系的位置关系即对应的坐标转换方法
                  订阅方:订阅话题信息,找到son01坐标系和son2坐标系之间的关系,已知一个坐标在son1中的坐标,转换为在son2中的坐标

launch文件:

<launch>
    <node pkg="tf2_ros" type="static_transform_publisher" name="son1" args="5 0 0 0 0 0 /world /son1" output="screen">
    <node pkg="tf2_ros" type="static_transform_publisher" name="son2" args="3 0 0 0 0 0 /world /son2" output="screen">
</launch>

第一步:

catkin_create_pkg tf01_many geometry_msgs roscpp rospy std_msgs tf2 tf2_geometry_msgs tf2_ros

第二步:CMakelist

​cmake_minimum_required(VERSION 3.0.2)
project(tf01_many)

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  tf2
  tf2_geometry_msgs
  tf2_ros
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES tf01_many
#  CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs tf2 tf2_geometry_msgs tf2_ros
#  DEPENDS system_lib
)

include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

add_executable(tf01_many_sub src/tf01_many_sub.cpp)

add_dependencies(tf01_many_sub ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(tf01_many_sub
  ${catkin_LIBRARIES}
)
​

第四步:cpp文件

# include "ros/ros.h"
# include "tf2_ros/transform_listener.h"
# include "tf2_ros/buffer.h"
# include "geometry_msgs/PointStamped.h"
# include "tf2_geometry_msgs/tf2_geometry_msgs.h"
# include "geometry_msgs/TransformStamped.h"

int main(int argc, char* argv[])
{
    setlocale(LC_ALL,"");
    ros::init(argc, argv, "tfs_sub");
    ros::NodeHandle n;
    //创建订阅对象
    tf2_ros::Buffer buffer;
    tf2_ros::TransformListener sub(buffer);
    //编写解析逻辑
    //创建坐标点
    geometry_msgs::PointStamped psAtSon1;
    psAtSon1.header.stamp = ros::Time::now();
    psAtSon1.header.frame_id = "son1";
    psAtSon1.point.x = 1.0;
    psAtSon1.point.y = 2.0;
    psAtSon1.point.z = 3.0;
    
    ros::Rate rate(10);
    while (ros::ok())
    {
        try
        {
            //计算是son1和son2的关系,TransformStamped函数可以解析多坐标系统中任意两个坐标之间的位置关系
            geometry_msgs::TransformStamped son1ToSon2 = buffer.lookupTransform("son2","son1",ros::Time(0));
            ROS_INFO("son1相对于son2的信息:父级:%s,子级:%s 偏移量(%.2f,%.2f,%.2f)",
                    son1ToSon2.header.frame_id.c_str(),
                    son1ToSon2.child_frame_id.c_str(),
                    son1ToSon2.transform.translation.x,
                    son1ToSon2.transform.translation.y,
                    son1ToSon2.transform.translation.z);
            //计算son1中的某个点在son2中的坐标值
            geometry_msgs::PointStamped psAtSon2 = buffer.transform(psAtSon1,"son2");
            ROS_INFO("坐标点在Son2中的值是(%.2f, %.2f,%.2f)",
                                        psAtSon2.point.x,
                                        psAtSon2.point.y,
                                        psAtSon2.point.z
                                        );
        }
        catch(const std::exception& e)
        {
            ROS_INFO("Error:%s", e.what());
        }
    }
    return 0;
}

4.tf2坐标关系查看工具

1、安装

sudo apt install ros-noetic-tf2-tools

2、启动

rosrun tf2_tools view_frames.py

二、rosbag包

一、作用

实现将程序的进程保存起来,事后还可以在重播

二、实现步骤

1.建立一个文件夹

2.在文件夹中建立××.bag文件用来保存录制信息

3.开始录制

rosbag record -a -o /home/zhangpeng/catkin_wstest/src/文件名.bag

4.查看文件

rosbag info /home/zhangpeng/catkin_wstest/src/bag/test_2021-08-26-17-00-25.bag

5.重播

rosbag play /home/zhangpeng/catkin_wstest/src/bag/test_2021-08-26-17-00-25.bag

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值