ROS学习(二)基础功能包

tf坐标变换 首先安装tf功能包
sudo apt-get install ros-melodic-trtle-tf
运行tf功能包demo
roslaunch turtle_tf turtle_tf_demo.launch
运行键盘节点rosrun turtlesim turtle_teleop_key
可观察到出现两只海龟,其中一只跟随始终跟随第一只位置变化ROS学习(二)基础功能包
文章图片

观察tf坐标系关系 1、运行rosrun tf view_frames,生成tf可视化工具生成pdf文件,保存在当前目录,如图体现三个坐标系
turtle1坐标系,world坐标系,turtle2坐标系位置关系
ROS学习(二)基础功能包
文章图片

2、rosrun tf tf_echo turtle1 turtle2
可观察到实时姿态,包括位置信息和旋转信息
3、利用rviz可视化工具观察坐标变换
rosrun rviz rviz -d ‘rospack find turtle_tf’/rviz/turtle_rviz.rviz
ROS学习(二)基础功能包
文章图片

tf坐标系监听与广播编程实现 创建tf功能包
catkin_create pkg learning_tf roscpp rospy turtlesim tf
创建tf广播器代码

#include #include #includestd::string turtle_name; void poseCallback(const turtlesim::PoseConstPtr& msg)//传入参数,海龟位置 { //创建tf广播器 static tf::TransformBroadcaster br; //创建实例,发布位置//初始化tf数据 tf::Transform transform; //4*4矩阵 transform.setOrigin(tf::Vector3(msg->x,msg->y,0.0)); //设置平移参数 tf::Quaternion q; //通过四元数设置旋转 q.setRPY(0,0,msg->theta); //两个坐标系姿态变化设置 transform.setRotation(q); //广播world与海龟坐标系之间的tf数据,添加当前时间戳,广播world和turtle_name 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]; //创建订阅者sub,订阅海龟位资话题 ros::NodeHandle node; //创建句柄 ros::Subscriber sub = node.subscribe(turtle_name+"/pose",10,&poseCallback); //循环等待回调函数 ros::spin(); return 0; }

创建tf监听器代码
#include #include//tf监听器 #include #includeint main(int argc,char** argv) { //初始化节点 ros::init(argc,argv,"my_tf_listener"); //创建句柄 ros::NodeHandle node; //请求产生turtle2 ros::service::waitForService("/spawn"); //发布spawn请求产生新海龟 ros::ServiceClient add_turtle = node.serviceClient("/spawn"); turtlesim::Spawn srv; add_turtle.call(srv); //创建发布turtle2速度控制指令的发布者 ros::Publisher turtle_vel = node.advertise("/turtle2/cmd_vel",10); //创建tf的监听器 tf::TransformListener listener; //监听任意两个坐标系关系ros::Rate rate(10.0); while (node.ok()) { //获取turtle1与turtle2坐标之间的tf数据 tf::StampedTransform transform; try { //等待变换,等待当前时间,等待3秒后超时提示错误 listener.waitForTransform("/turtle2","/turtle1",ros::Time(0),ros::Duration(3.0)); //查询变换,查询当前时间,结果保存在transform中 listener.lookupTransform("/turtle2","/turtle1",ros::Time(0),transform); } catch (tf::TransformException &ex) {}//根据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; }

配置tf广播器与监听器代码编译规则
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:=turtle1_tf_broadcaster /turtle1 rosrun learning_tf turtle_tf_broadcaster__name:=turtle2_tf_broadcaster /turtle2 rosrun learning_tf turtle_tf_listener rosrun turtlesim turtle_teleop_key

launch文件语法 launch文件中的根元素采用标签定义
启动节点 ROS学习(二)基础功能包
文章图片


pkg:节点所在功能包名称
type:节点的可执行文件名称
name:节点运行时的名称
output:打印节点日志信息到当前终端
respawn:控制节点挂掉自动重启
required:某个节点必须启动
ns:命名空间,避免命名冲突
args:给节点输入参数
参数设置 ROS学习(二)基础功能包
文章图片

ROS学习(二)基础功能包
文章图片

重映射 ROS学习(二)基础功能包
文章图片

嵌套 ROS学习(二)基础功能包
文章图片

Rviz 【ROS学习(二)基础功能包】ROS学习(二)基础功能包
文章图片

    推荐阅读