Ros学习笔记(八)——各部分代码实现(三)
文章目录
1.ROS中的坐标管理系统:
在看代码前,首先让我们安装一下turtle-tf功能包。
sudo apt-get install ros-noetic-turtle-tf
输入(运行节点):
roslaunch turtle_tf turtle_tf_demo.launch
注意:这里报错yawl的同学,需要输入如下命令把python的版本改变:
sudo apt install python-is-python3
输入: rosrun turtlesim turtle_teleop_key(控制小乌龟)
首先,这里讲讲报错怎么解决吧,孩子就一个报错卡了好久。
如果报错: TypeError: cannot use a string pattern on a bytes-like object
sudo apt install vim
sudo vim /opt/ros/noetic/lib/tf/view_frames
将第89行代码m = r.search更改为m = r.search(vstr.decode(‘utf-8’))
随后: rosrun tf view_frames
随后就生成了pdf文件:
上图中,world坐标系表示的是全局坐标系,turtle1、turtle2分别是两个小乌龟坐标系,他们会不断的重叠,他们二者相对于world的相对位置是不断变化的,
此时输入: rosrun tf tf_echo turtle1 turtle2
就可看到他们的实时位置。
此时可调用RViz(可视化工具)观察小乌龟的
rosrun rviz rviz -d rospack find turtle_tf
/rviz/turtle_rviz.rviz
计算式如下:
2.tf坐标系广播与监听的编程实现
输入(建立功能包):
catkin_create_pkg learning_tf roscpp rospy tf turtlesim
创建如下两个cpp文件:
turtle_tf_broadcaster.cpp
/***********************************************************************
Copyright 2020 GuYueHome (www.guyuehome.com).
***********************************************************************/
/**
* 该例程产生tf数据,并计算、发布turtle2的速度指令
*/
#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数据
tf::Transform transform;
transform.setOrigin( tf::Vector3(msg->x, msg->y, 0.0) );
tf::Quaternion q;
q.setRPY(0, 0, msg->theta);
transform.setRotation(q);
// 广播world与海龟坐标系之间的tf数据
br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name));
}
int main(int argc, char** argv)
{
// 初始化ROS节点
ros::init(argc, argv, "my_tf_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;
};
1.定义TF广播器
2.创建坐标变换值
3.发布坐标变换
turtle_tf_listener.cpp
/***********************************************************************
Copyright 2020 GuYueHome (www.guyuehome.com).
***********************************************************************/
/**
* 该例程监听tf数据,并计算、发布turtle2的速度指令
*/
#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节点
ros::init(argc, argv, "my_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的监听器
tf::TransformListener listener;
ros::Rate rate(10.0);
while (node.ok())
{
// 获取turtle1与turtle2坐标系之间的tf数据
tf::StampedTransform transform;
try
{
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的速度控制指令
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;
};
1.定义TF监听器
2.查找坐标变换
首先,向往常一样添加Cmake中的编译规则:
add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp)
target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES})
add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})
随后编译: catkin_make
先调出小海龟: roscore
rosrun turtlesim turtlesim_node
再输入: rosrun learning_tf turtle_tf_broadcaster __name:=turtlel_tf_broadcaster /turtle1
rosrun learning_tf turtle_tf_broadcaster _name:=turtle2_tf_broadcaster /turtle2
rosrun learning_tf turtle_tf_listener
效果如上(注意:此时用方向键控制。)
3.launch文件启动和使用方法:
launch文件的根元素采用launch标签定义
(1).node
启动节点:
调用如下格式:
<node pkg="package-name" type="executable-name" name="node-name" />
其中,pkg表示节点所在功能包的名称
type表示节点的可执行文件的名称
name表示节点运行时的名称
例如:
<node pkg="turtlesim" name="sim1" type="turtlesim_node" />
其中,功能包名为“turtlesim” 节点可执行文件的名称“turtlesim_node” 节点运行时的名称“name”
(2).param
设置ROS系统运行的参数
<param name="output_frame"value="odom"/>
其中,name表示参数名
value表示参数值
加载参数文件中的多个参数:
<rosparam file="params.yaml" command="load" ns=“params" />
其中,params.yaml为参数文件名
load表示加载
params表示加载的参数
(3).arg
launch文件中的局部变量,仅限于launch文件中使用。
<arg name="arg-name" default="arg-value"/>
其中,name表示参数名
value表示参数值
调用如下:
<param name="foo" value="$(arg arg-name)"/>
<node name="node" pkg="package" type="type " args="$(arg arg-name)" />
(4).remap
重映射ROS计算图中资源的命名,实质就是改资源的名字。
<remap from="/turtlebot/cmd_vel" to="/cmd_vel" />
其中,from表示原命名
to表示映射后的命名
(5).include
包含其他launch文件。
<include file="s(dirname)/other.launch" />
其中file表示其他launch文件。
可参考如下格式编写launch文件:
4.常用可视化工具
一下举出几个例子给大家参考:
rqt_console :
首先我们要开启RosMaster ,输入: roscore
再输入: rqt_+(两个tab键)
就可以看到rqt的所有可视化工具。
调用出小海龟撞墙后,就会出现图示警告。
rqt_plot:
如左下角调用出的图表。
11.27学习笔记
ROS学习笔记(二)——python、C++编译器以及ROS的安装_风声向寂的博客-优快云博客
ROS学习笔记(三)——ROS的简单了解_风声向寂的博客-优快云博客
ROS学习笔记(四)——ROS命令行工具使用讲解_风声向寂的博客-优快云博客
ROS学习笔记(五)——工作空间和功能包_风声向寂的博客-优快云博客