ROS学习(三)——常用组件

1.launch文件

launch文件是ROS中一种同时启动多个节点的途径,它可以自动启动ROS Master节点管理器,并且可以实现每个节点的各种配置,便于多个节点的操作。

1.1 launch的基本元素

一个简单的launch文件表示如下:

<launch>
	<node pkg="turtlesim" name="sim1" type="turtlesim_node">
	<node pkg="turtlesim" name="sim2" type="turtlesim_node">
</launch>

上述为一个简单的launch文件,使用xml形式描述,其中xml文件必须包含一个根元素,使用< launch >标签定义,其他内容必须在这个标签之中,即:

<launch>
	.......
</launch>

< node > 表示ROS节点,是启动文件的核心,命名规则如下:

<node pkg="package-name" name="node-name" type="executable-name" />

其中pkg定义节点所在的功能包名称,type定义节点的可执行文件名称,这两个属性和终端中直接使用rosrun执行节点的输入参数相同,name用于定义节点运行的名称。
除< node >之外,还有< arg >、< param >、< remap >等常用的标签元素。

1.2参数设置

< param >
< param >使用方法如下:

<param name="output_frame" value="odom" />

运行launch文件后,output_frame的值被设置为odom。也可以使用< rosparam >形式

<rosparam file="$(find wdnav_pr2)/config/costma[_common_params.yaml" command="load" ns="local_costmap" />

该方式可以帮助我们讲一个yaml格式文件中的参数加载到ROS的参数服务器中,需要设置command属性为"load",还可以选择设置命名空间。
< arg >
类似于launch文件内部的局部变量,其语法如下:

<arg name="arg-name" default="arg-value" />

launch文件中需要使用argument时,使用如下方式调用:

<param name="foo" value="$(arg arg-name)" />
<node name="node" pkg="package" type="type" args="$(arg arg-name)" />

重映射

ROS提供了重映射机制,可以将其他来源的功能包的接口名称重映射供自己的系统使用。如下例所示,turtlebot的键盘控制节点发布的速度控制指令话题可能是/turtlebot/cmd_vel,自己的机器人订阅的速度控制话题为/cmd_vel,可以使用如下重映射指令:

<remap from “/turtlebot/cmd_vel” to="/cmd_vel" />

嵌套复用

ROS系统中的launch文件可能会存在依赖关系,若想直接复用已有的launch文件的内容,可以使用< inclued >,命令如下:

<include file="$(dirname)/other.launch" />

2.TF坐标变换

TF功能包可以帮助用户随时间跟踪多个坐标系,采用了树形数据结构。其使用步骤如下:

  • 监听TF变换:接收并缓存系统中发布的所有坐标变换数据,并从中查询需要的坐标变换关系
  • 广播TF变换:向系统中广播坐标系之间的坐标变换关系。
2.1 TF工具

tf_monitor可以用于打印TF树中所有坐标系的发布状态,如果像查看指定坐标系之间的发布状态,使用命令如下:

tf_monitor <source_frame> <target_frame>

tf_echo可以查看指定坐标系之间的变换关系

tf_echo <source_frame> <target_frame>

tf_transform_publisher可以发布两个坐标系之间的静态坐标变换,格式如下

//偏移+旋转
static_transform_publisher x y z yaw pitch roll frame_id child_id period_in_ms
//四元数
static_transform_publisher x y z qx qy qz qw frame_id child_id period_in_ms

view_frames为可视化调试工具,可以生成pdf文件,显示整棵TF树信息

//生成pdf
rosrun tf view_frames
//查看pdf
evince frames.pdf
2.2 创建TF广播器与监听器

实现两只乌龟的跟随运动

创建广播器

继承ROS学习(二)部分的实践,在catkin_ws/src/wk_tutorials/src文件夹下创建broadcaster.cpp文件,文件内容如下:

#include<ros/ros.h>
#include<tf/transform_broadcaster.h>
#include<turtlesim/Pose.h>

std::string turtle_name;

//回调函数
void poseCallback(const turtlesim::PoseConstPtr& msg)
{
    //创建tf广播器
    //类似于创建一个发布者
    static tf::TransformBroadcaster br;

    //定义存放转换信息(平动、转动)的变量
    tf::Transform transform;

    //设置坐标原点
    //即子坐标系的坐标原点在父坐标系下的坐标
    transform.setOrigin(tf::Vector3(msg->x,msg->y,0.0));

    //定义旋转
    //roll绕x轴,pitch绕y轴,yaw绕z轴
    tf::Quaternion q;
    q.setRPY(0,0,msg->theta);

    //设置旋转,Set the rotational element by Quaternion.
    transform.setRotation(q);

    br.sendTransform(tf::StampedTransform(transform,ros::Time::now(),"world",turtle_name));
    //sendtransform函数发布Tf变换,需要四个参数:转换本身(存储变换关系的变量),广播时的时间戳,父坐标系,子坐标系
}



int main(int argc,char ** argv)
{
    //初始化节点
    ros::init(argc, argv, "broadcaster");

    if(argc != 2)
    {
        ROS_ERROR("need turtle name as argument");
        return -1;
    }
    turtle_name = argv[1];

    //创建节点句柄
    ros::NodeHandle node;   
    ros::Subscriber sub = node.subscribe(turtle_name+"/pose",10,&poseCallback);
    //创建订阅者,话题名、队列长度、回调函数

    ros::spin();
    return 0;
};

创建监听器

在catkin_ws/src/wk_tutorials/src下建立tf_listener文件

#include<ros/ros.h>
#include<tf/transform_listener.h>
#include<geometry_msgs/Twist.h>
#include<turtlesim/Spawn.h>

 int main(int argc, char *argv[])
{
    //初始化节点
    ros::init(argc, argv, "tf_listener");
    
    ros::NodeHandle node;

    // 通过服务调用,产生第二只乌龟turtle2
    ros::service::waitForService("spawn");
    ros::ServiceClient add_turtle = 
        node.serviceClient<turtlesim::Spawn>("spawn");
    turtlesim::Spawn srv;
    add_turtle.call(srv);

    //定义turtle2的速度发布器
    ros::Publisher turtle_vel = 
        node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel",10);

    tf::TransformListener listener;

    ros::Rate rate(10.0);
    while (node.ok())
    {

       tf::StampedTransform transform;
       try
       {
           // 查找turtle2与turtle1的坐标变换
            listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0));
            listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);
       }
       catch (tf::TransformException &ex)
       {
            ROS_ERROR("%s",ex.what());
            ros::Duration(1.0).sleep();
            continue;
       }
       // 根据turtle1和turtle2之间的坐标变换,计算turtle2需要运动的线速度和角速度
        // 并发布速度控制指令,使turtle2向turtle1移动
        geometry_msgs::Twist vel_msg;
        vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(),
                                        transform.getOrigin().x());
        vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) +
                                      pow(transform.getOrigin().y(), 2));
     turtle_vel.publish(vel_msg);

        rate.sleep();
       
    }
    return 0;
}

修改CmakeLists

首先添加功能包依赖

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  tf
  turtlesim)

然后添加:

add_executable(broadcaster src/broadcaster.cpp)
target_link_libraries(broadcaster ${catkin_LIBRARIES})
add_executable(tf_listener src/tf_listener.cpp)
target_link_libraries(tf_listener ${catkin_LIBRARIES})

修改package.xml

<buildtool_depend>catkin</buildtool_depend>

 <build_depend>geometry_msgs</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>tf</build_depend>
  <build_depend>turtlesim</build_depend>
  <build_export_depend>geometry_msgs</build_export_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>tf</build_export_depend>
  <build_export_depend>turtlesim</build_export_depend>
  <exec_depend>geometry_msgs</exec_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>tf</exec_depend>
  <exec_depend>turtlesim</exec_depend>

运行

首先返回catkin_ws目录下使用catkin_make命令进行编译,编译成功后运行下述命令

roslaunch wk_tutorials demo.launch

可以使用键盘控制一只小乌龟,另一只会跟随运动,结果如下:
在这里插入图片描述

3.QT工具箱

QT工具箱可以方便用户进行可视化调试和显示,常用命令如下:

  • rqt_console工具可以用来图像化显示ROS系统运行状态中的所有日志消息
  • rqt_graph可以以图形化显示当前ROS系统中的计算图
  • rqt_plot可以将需要显示的数据在xy坐标系中使用曲线秒回
  • ros_reconfigure可以在不重启系统的情况下动态配置ROS系统中的参数,工具启动命令如下:
rosrun rqt_reconfigure rqt_reconfigure

4. 数据记录与回放

rosbag功能包提供了数据记录与回放功能,下面给出示意例程

4.1 记录数据

启动键盘控制乌龟历程所需的所有节点

roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key

此时可以在终端中通过键盘控制小乌龟的移动,执行下述命令查看ROS中存在的话题:

rostopic list -v

在这里插入图片描述
使用rosbag抓取上述话题的消息,打包成一个文件放置到指定文件夹中

mkdir ~/bagfiles
cd ~/bagfiles
//数据记录,-a表示记录所有发布的消息
rosbag record -a

控制小乌龟移动一段时间,使用Ctrl+C终止数据记录

4.2 回放数据

使用rosbag中的info命令查看数据记录文件的详细信息

rosbag info <your bagfile>

在这里插入图片描述

终止之前的turtle_teleop_key节点,并重启turtlesim_node,使用下列命令回放:

rosbag play <your bagfile>

此时,小乌龟运动轨迹与之前保存的相同

参考文章:
[1] https://blog.csdn.net/qq_43481884/article/details/102768426
[2] https://blog.csdn.net/qq_43481884/article/details/102799048

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

space_dandy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值