安装Ros中 tf 相关功能包
sudo apt-get install ros-melodic-turtle-tf
启动launch文件,这个launch文件相当于一个脚本,可以一次性启动很多节点
roslaunch turtle_tf turtle_tf_demo.launch
启动海龟控制节点
rosrun turtlesim turtle_teleop_key
能够监听当前时刻所有通过ROS广播的tf坐标系,并绘制出树状图表示坐标系之间的连接关系保存到离线文件中,监听5秒后,保存5秒内坐标系之间的关系,会生成一个pdf文件。
rosrun tf view_frames
使用tf_echo工具可以查看两个广播参考系之间的关系。
rosrun tf tf_echo
[reference_frame
] [target_frame
]
例如:
rosrun tf tf_echo turtle1 turtle2
通过rvize可视化工具更加形象的看到这三者之间的关系。
rosrun rviz rviz -d
'rospack find turtle_tf' /rviz/turtle.rviz
cd ~/catkin_ws/src
catkin_create_pkg learning_tf roscpp rospy tf turtlesim
如何实现一个tf广播器
如何实现一个TF监听器
在创建的 learning_tf 目录中的src文件夹下创建一个 cpp文件
cd ~/catkin_ws/src/learning_tf/src
touch turtle_tf_broadcaster.cpp
在 turtle_tf_broadcaster.cpp 文件中写入以下代码。
以下代码的功能:产生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
)
{static tf
::TransformBroadcaster br
;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
);br
.sendTransform(tf
::StampedTransform(transform
, ros
::Time::now(), "world", turtle_name
));
}int main(int argc
, char** argv
)
{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;
};
在创建的 learning_tf 目录中的src文件夹下创建一个 cpp文件
cd ~/catkin_ws/src/learning_tf/src
touch turtle_tf_listener.cpp
在 turtle_tf_listener.cpp 文件中写入以下代码。
以下代码的功能:监听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
::init(argc
, argv
, "my_tf_listener");ros
::NodeHandle node
;ros
::service
::waitForService("/spawn");ros
::ServiceClient add_turtle
= node
.serviceClient
<turtlesim
::Spawn
>("/spawn");turtlesim
::Spawn srv
;add_turtle
.call(srv
);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{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;}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.txt中添加以下代码:
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})
编译项目
cd ~/catkin_ws
catkin_make
设置环境变量,让系统能够找到该工作空间
source devel/setup.bash
启动ROS Master
roscore
启动小海龟仿真器
rosrun turtlesim turtlesim_node
发布/turtle1海龟坐标系关系
rosrun learning_tf turtle_tf_broadcaster __name:
=turtle1_tf_broadcaster /turtle1
注:turtle_tf_broadcaster __name:=turtle1_tf_broadcaster 重新命名
发布/turtle2海龟坐标系关系
rosrun learning_tf turtle_tf_broadcaster __name:
=turtle2_tf_broadcaster /turtle2
启动自定义的节点
rosrun learning_tf turtle_tf_listener
启动海龟控制节点
rosrun turtlesim turtle_teleop_key
用Python实现的步骤:
cd ~/catkin_ws/src/learning_tf
创建 scripts 文件夹
mkdir scripts
cd scripts
创建 turtle_tf_broadcaster.py Python文件
touch turtle_tf_broadcaster.py
用Python实现的代码:
以下代码的功能:请求/show_person服务,服务数据类型learning_service::Person
import roslib
roslib
.load_manifest
('learning_tf')
import rospy
import tf
import turtlesim
.msg
def handle_turtle_pose(msg
, turtlename
):br
= tf
.TransformBroadcaster
()br
.sendTransform
((msg
.x
, msg
.y
, 0),tf
.transformations
.quaternion_from_euler
(0, 0, msg
.theta
),rospy
.Time
.now
(),turtlename
,"world")if __name__
== '__main__':rospy
.init_node
('turtle_tf_broadcaster')turtlename
= rospy
.get_param
('~turtle')rospy
.Subscriber
('/%s/pose' % turtlename
,turtlesim
.msg
.Pose
,handle_turtle_pose
,turtlename
)rospy
.spin
()
创建 turtle_tf_listener.py Python文件
touch turtle_tf_listener.py
用Python实现的代码:
以下代码的功能:请求/show_person服务,服务数据类型learning_service::Person
import roslib
roslib
.load_manifest
('learning_tf')
import rospy
import math
import tf
import geometry_msgs
.msg
import turtlesim
.srv
if __name__
== '__main__':rospy
.init_node
('turtle_tf_listener')listener
= tf
.TransformListener
()rospy
.wait_for_service
('spawn')spawner
= rospy
.ServiceProxy
('spawn', turtlesim
.srv
.Spawn
)spawner
(4, 2, 0, 'turtle2')turtle_vel
= rospy
.Publisher
('turtle2/cmd_vel', geometry_msgs
.msg
.Twist
,queue_size
=1)rate
= rospy
.Rate
(10.0)while not rospy
.is_shutdown
():try:(trans
,rot
) = listener
.lookupTransform
('/turtle2', '/turtle1', rospy
.Time
(0))except (tf
.LookupException
, tf
.ConnectivityException
, tf
.ExtrapolationException
):continueangular
= 4 * math
.atan2
(trans
[1], trans
[0])linear
= 0.5 * math
.sqrt
(trans
[0] ** 2 + trans
[1] ** 2)cmd
= geometry_msgs
.msg
.Twist
()cmd
.linear
.x
= linearcmd
.angular
.z
= angularturtle_vel
.publish
(cmd
)rate
.sleep
()
注意:需要将Python设置为可执行文件。
启动ROS Master
roscore
启动小海龟仿真器
rosrun turtlesim turtlesim_node
发布/turtle1海龟坐标系关系
rosrun learning_tf turtle_tf_broadcaster.py __name:
=turtle1_tf_badcaster _turtle:
=turtle1
发布/turtle2海龟坐标系关系
rosrun learning_tf turtle_tf_broadcaster.py __name:
=turtle2_tf_badcaster _turtle:
=turtle2
启动自定义的监听节点
rosrun learning_tf turtle_tf_listener.py
启动海龟控制节点
rosrun turtlesim turtle_teleop_key
总结
以上是生活随笔为你收集整理的ROS系统实现 tf坐标系广播与监听的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。