Tutorial2
一.写一个tf2的broadcaster
本教程关于怎样broadcast一个机器人的坐标系到tf2上.
1.创建一个learning_tf2包
catkin_create_pkg learning_tf2 tf2 tf2_ros roscpp rospy turtlesim
本文要broadcast变化中的turtles的坐标系.
新建文件src/turtle_tf2_broadcaster.cpp
//
// Created by gary on 2019/9/4.
// #include <ros/ros.h>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2_ros/transform_broadcaster.h>
#include <geometry_msgs/TransformStamped.h>
#include <turtlesim/Pose.h> std::string turtle_name; void poseCallback(const turtlesim::PoseConstPtr& msg)
{
static tf2_ros::TransformBroadcaster br;
geometry_msgs::TransformStamped transformStamped; transformStamped.header.stamp = ros::Time::now();
transformStamped.header.frame_id = "world";
transformStamped.child_frame_id = turtle_name;
transformStamped.transform.translation.x = msg->x;
transformStamped.transform.translation.y = msg->y;
transformStamped.transform.translation.z = 0.0; tf2::Quaternion q;
q.setRPY(, , msg->theta);
transformStamped.transform.rotation.x = q.x();
transformStamped.transform.rotation.y = q.y();
transformStamped.transform.rotation.z = q.z();
transformStamped.transform.rotation.w = q.w();
br.sendTransform(transformStamped);
} int main(int argc, char**argv)
{
ros::init(argc, argv, "my_tf2_broadcaster");
ros::NodeHandle private_node("~");
if(!private_node.hasParam("turtle"))
{
if(argc != )
{
ROS_ERROR("need turtle name as argument");
return -;
}
turtle_name = argv[];
}
else
{
private_node.getParam("turtle", turtle_name);
}
ros::NodeHandle node;
ros::Subscriber sub = node.subscribe(turtle_name + "/pose", , &poseCallback); ros::spin();
return ;
}
添加一个launch文件
start_demo.launch
<launch>
<!-- Turtlesim Node-->
<node pkg="turtlesim" type="turtlesim_node" name="sim"/> <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/>
<!-- Axes -->
<param name="scale_linear" value="" type="double"/>
<param name="scale_angular" value="" type="double"/> <node pkg="learning_tf2" type="turtle_tf2_broadcaster"
args="/turtle1" name="turtle1_tf2_broadcaster" />
<node pkg="learning_tf2" type="turtle_tf2_broadcaster"
args="/turtle2" name="turtle2_tf2_broadcaster" /> </launch>
修改CMakeLists.txt,添加如下
add_executable(turtle_tf2_broadcaster src/turtle_tf2_broadcaster.cpp)
target_link_libraries(turtle_tf2_broadcaster
${catkin_LIBRARIES}
) ## Mark other files for installation (e.g. launch and bag files, etc.)
install(FILES
start_demo.launch
# myfile2
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
然后编译之.
启动:
$ roslaunch learning_tf2 start_demo.launch
启动之后,就可以在turtle sim中看到一个turtle.
2.查看结果
$ rosrun tf tf_echo /world /turtle1
通过上面的命令可以看到turtle1在world中的位置信息.目前turtle2的信息没有.
二. 写一个tf2的listener
创建文件 src/turtle_tf2_listener.cpp
//
// Created by gary on 2019/9/4.
//
#include <ros/ros.h>
#include <tf2_ros/transform_listener.h>
#include <geometry_msgs/TransformStamped.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Spawn.h> int main(int argc, char** argv)
{
ros::init(argc, argv, "my_tf2_listener");
ros::NodeHandle node; ros::service::waitForService("spawn");
ros::ServiceClient spawner = node.serviceClient<turtlesim::Spawn>("spawn");
turtlesim::Spawn turtle;
turtle.request.x = ;
turtle.request.y = ;
turtle.request.theta = ;
turtle.request.name = "turtle2"; spawner.call(turtle);
ros::Publisher turtle_vel =
node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel", );
tf2_ros::Buffer tfBuffer;
tf2_ros::TransformListener tfListener(tfBuffer); ros::Rate rate(10.0); while(node.ok())
{
geometry_msgs::TransformStamped transformStamped;
try
{
transformStamped = tfBuffer.lookupTransform("turtle2", "turtle1",ros::Time());
}
catch (tf2::TransformException &ex)
{
ROS_WARN("%s",ex.what());
ros::Duration(1.0).sleep();
continue;
}
geometry_msgs::Twist vel_msg;
vel_msg.angular.z = 4.0 * atan2(transformStamped.transform.translation.y,
transformStamped.transform.translation.x);
vel_msg.linear.x = 0.5 * sqrt(pow(transformStamped.transform.translation.x,) +
pow(transformStamped.transform.translation.y, ));
turtle_vel.publish(vel_msg);
rate.sleep(); }
return ;
}
CMakeLists.txt
add_executable(turtle_tf2_listener src/turtle_tf2_listener.cpp)
target_link_libraries(turtle_tf2_listener
${catkin_LIBRARIES}
)
tf2_ros::Buffer tfBuffer;
tf2_ros::TransformListener tfListener(tfBuffer);
说明一下:
创建了一个TransformListener对象,一旦TransformListener被创建,它就开始接收tf2的变换,且会默认保存10s的变换.
transformStamped = tfBuffer.lookupTransform("turtle2", "turtle1",
ros::Time(0));
参数说明:
- We want the transform to this frame (target frame) ...
- ... from this frame (source frame).
The time at which we want to transform. Providing ros::Time(0) will just get us the latest available transform.
- Duration before timeout. (optional, default=ros::Duration(0.0))
在launch文件中添加如下
<launch>
<!--Turtlesim Node-->
<node pkg = "turtlesim" type = "turtlesim_node" name="sim"/>
<node pkg = "turtlesim" type = "turtle_teleop_key" name = "teleop" output = "screen"/> <!-- Axes -->
<param name="scale_linear" value="" type="double"/>
<param name="scale_angular" value="" type="double"/> <node pkg = "learning_tf2" type = "turtle_tf2_broadcaster"
args = "/turtle1" name ="turtle1_tf2_broadcaster" output = "screen" /> <node pkg = "learning_tf2" type = "turtle_tf2_broadcaster"
args = "/turtle2" name ="turtle2_tf2_broadcaster" output = "screen" />
<node pkg="learning_tf2" type="turtle_tf2_listener"
name="listener" />
</launch>
启动launch文件
$ roslaunch learning_tf2 start_demo.launch
Tutorial2的更多相关文章
- RDF和Jena RDF API简介
这是官方文章<An Introduction to RDF and the Jena RDF API>的译文.原文是在刺猬的温驯这里看到的.其中的图片没法显示了,还有一段丢失了.于是我在此 ...
- Redis 学习笔记续
Redis - 数据类型 Redis支持5种类型的数据类型,它描述如下的: 字符串 Redis字符串是字节序列.Redis字符串是二进制安全的,这意味着他们有一个已知的长度没有任何特殊字符终止,所以你 ...
- Git引用
原文: http://gitbook.liuhui998.com/7_3.html git中,分支(branch), 远程跟踪分支(remote-tracking branch)以及标签(tag)都是 ...
- React JS快速入门教程
翻译至官方文档<Tutorial>http://facebook.github.io/react/docs/tutorial.html 转载请注明出处:http://blog.csdn.n ...
- React学习一
一.运行起来react 1.引入react库 引入对应的js即可,第三方cdn引入 <script src="https://cdnjs.cloudflare.com/ajax/lib ...
- Struts2 配置详解
1. web.xml 此文件的配置可以参看struts2的示例文档 <filter> <filter-name>struts2</filter-name> < ...
- C++混合编程之idlcpp教程Python篇(4)
上一篇在这 C++混合编程之idlcpp教程Python篇(3) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial2中,同样加入了三个文件 Pyt ...
- C++混合编程之idlcpp教程Lua篇(4)
上一篇在这 C++混合编程之idlcpp教程Lua篇(3) 与前面的工程相似,工程LuaTutorial2中,同样加入了三个文件 LuaTutorial2.cpp, Tutorial2.i, tut ...
- jQuery 图片剪裁插件初探之 Jcrop
主页:http://deepliquid.com/content/Jcrop.html 官方下载地址:http://deepliquid.com/content/Jcrop_Download.html ...
随机推荐
- RAC搭建---自己做
一.本地磁盘是指你本身加上去的磁盘,只能本机使用的.共享磁盘是指可以多台机器同时读取写入.你做RAC就要用到共享存储: 二.ORC分区一般1G*3 数据分区5G*3 ,FRA分区一般5G*3 这 ...
- 洛谷 P1407 稳定婚姻
问题描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关.25岁的姗姗和男友谈恋爱半年就结婚,结婚不到两 ...
- [POJ 1911] 棋盘
问题描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着 ...
- 永久禁用Win10驱动程序强制签名
1.在开始按钮点击右键,选择“命令提示符(管理员)” 2.执行以下命令(复制后,在命令提示符中单击鼠标右键即可完成粘贴,然后按回车键执行): bcdedit.exe /set nointegrityc ...
- Delphi GridPanel Percent百分比设置
可能很多人都有这个困扰,为什么每次设置一个百分比后,值都会改变,只有设置成absolute才会正常,经摸索发现,是因为精度引起,设置percent的时候,需要将精确到多个小数位.如要有3列,需要设置 ...
- 用Jquery方法实现的简单下滑菜单效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Python 爬虫实战(1):分析豆瓣中最新电影的影评
目标总览 主要做了三件事: 抓取网页数据 清理数据 用词云进行展示 使用的python版本是3.6 一.抓取网页数据 第一步要对网页进行访问,python中使用的是urllib库.代码如下: from ...
- P2627 修剪草坪 (单调队列优化$dp$)
题目链接 Solution 70分很简单的DP,复杂度 O(NK). 方程如下: \[f[i][1]=max(f[j][0]+sum[i]-sum[j])\]\[f[i][0]=max(f[i-1][ ...
- 【CF1257D】Yet Another Monster Killing Problem【贪心】
题意:给定一些怪物,每天可以选一个勇士进去打怪,每个勇士每天只能打不超过si个怪物,每个勇士只能打能力值≤pi的怪物,问最少多少天打完所有怪物 题解:贪心,每天尽可能多的去打怪,那么存一个对于长度为i ...
- asp.net开发微信公众平台----目录汇总-持续更新
1.[c#]asp.net微信公众平台开发(1)数据库设计 2.[c#]asp.net微信公众平台开发(2)多层架构框架搭建和入口实现 3.[c#]asp.net微信公众平台开发(3)微信消息封装及反 ...