例题:广播并监听机器人的坐标变换,已知激光雷达和机器人底盘的坐标关系,求解激光雷达数据在底盘坐标系下的坐标值?
ROS的TF编程是对于嵌入式的进阶学习,有助于我们理解机器人运动与实时获取位置信息的方式,学习TF编程,我们就的指导TF功能包,什么是ROS的TF功能包?
ROS的TF功能包:
TF功能包,可以通过广播TF变换和监听TF变换获取如下坐标变换关系:
机器人局部坐标系相对于全局坐标系的关系。
机器人夹取的物体相对于机器人中心坐标系的位置.
机器人中心坐标系相对于全局坐标系的位置。
本次博客,我们就用上文所给的例子来进行TF编程的学习,话不多说,一起来看吧!
cd ~/ros/src/comm/src
注意:ros是我的ros工作空间、comm是自己的ros工程包,小伙伴们根据自己的进行修改哦!
touch broadCaster.cpp
gedit broadCaster.cpp
/**
* 该例程产生tf数据,并计算、发布base_laser的位置指令
*/
#include
#include
int main(int argc, char** argv){
// 初始化ROS节点
ros::init(argc, argv, "robot_tf_broadcaster");
// 订阅base_link的位置话题
ros::NodeHandle node;
// 创建tf的广播器
static tf::TransformBroadcaster br;
while(node.ok()){
// 初始化tf数据
tf::Transform transform;
transform.setOrigin( tf::Vector3(0.1, 0.0, 0.2) );
transform.setRotation( tf::Quaternion(0,0,0,1) );
// 广播base_link与base_laser坐标系之间的tf数据
br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "base_link", "base_laser"));
}
return 0;
};
创建一个新的终端,我们命名为终端1,输入如下命令:
touch robListener.cpp
gedit robListener.cpp
/**
* 该例程监听tf数据,并计算、发布base_laser的位置指令
*/
#include
#include
#include
int main(int argc, char** argv){
// 初始化ROS节点
ros::init(argc, argv, "robot_tf_listener");
// 创建节点句柄
ros::NodeHandle node;
// 创建tf的监听器
tf::TransformListener listener;
ros::Rate rate(10.0);
while (node.ok()){
//我们将在base_laser帧中创建一个要转换为base_link帧的点
geometry_msgs::PointStamped laser_point;
laser_point.header.frame_id = "base_laser";
//我们将在我们的简单示例中使用最近可用的转换
laser_point.header.stamp = ros::Time();
//laser_point检测点获取
laser_point.point.x = 0.3;
laser_point.point.y = 0.0;
laser_point.point.z = 0.0;
try{
// 等待获取监听信息base_link和base_laser
listener.waitForTransform("base_link", "base_laser", ros::Time(0), ros::Duration(3.0));
geometry_msgs::PointStamped base_point;
listener.transformPoint("base_link", laser_point, base_point);
ROS_INFO("base_laser: (%.2f, %.2f. %.2f) -----> base_link: (%.2f, %.2f, %.2f) at time %.2f",
laser_point.point.x, laser_point.point.y, laser_point.point.z,
base_point.point.x, base_point.point.y, base_point.point.z, base_point.header.stamp.toSec());
}
catch(tf::TransformException& ex){
ROS_ERROR("Received an exception trying to transform a point from \"base_laser\" to \"base_link\": %s", ex.what());
}
rate.sleep();
}
return 0;
};
到这里,我们的TF监听文件就创建好了,如下:
接下来就是修改CMakeLists.txt文件啦!
cd ~/ros/src/comm/
gedit CMakeLists.txt
add_executable(broadCaster src/broadCaster.cpp)
target_link_libraries(broadCaster ${catkin_LIBRARIES})
add_executable(robListener src/robListener.cpp)
target_link_libraries(robListener ${catkin_LIBRARIES})
tf
如下所示:
到这里,我们的CMakeLists.txt文件就修改完成,点击保存,关闭文件!
cd ~/ros
catkin_make
出现如下编译进度100%,这编译代码成功,如果不成功,则可以根据提示的错误信息进行修改:
让我们编写的代码生效
source ./devel/setup.bash
1)、新建一个终端,我们命令为终端2,然后启动
roscore
cd ~/ros
source ./devel/setup.bash
在终端3输入以下代码,不忙按回车
rosrun comm robListener
1)、在终端1输入以下命令,然后回车,紧接着在终端3回车,观察终端1和3的变化
rosrun comm broadCaster
运行后,我们可以观察到如下图的情况:
上图可以看出,终端3可以在监听处获得base_laser和base_link的坐标关系了。
2)、Ctrl+C关闭运行的程序,如下图:
以上就是本次博客的全部内容了,希望本次博客,对小伙伴们学习ROS TF编程有一定的帮助哦!感谢大家阅读,记得点赞、关注哦!遇到问题的小伙伴在评论区留言,一起讨论问题所在吧!林君学长耐心为大家解决哦!
陈一月的又一天编程岁月^ _ ^