tf坐标变换 首先安装tf功能包
sudo apt-get install ros-melodic-trtle-tf
运行tf功能包demo
roslaunch turtle_tf turtle_tf_demo.launch
运行键盘节点rosrun turtlesim turtle_teleop_key
可观察到出现两只海龟,其中一只跟随始终跟随第一只位置变化
文章图片
观察tf坐标系关系 1、运行rosrun tf view_frames,生成tf可视化工具生成pdf文件,保存在当前目录,如图体现三个坐标系
turtle1坐标系,world坐标系,turtle2坐标系位置关系
文章图片
2、rosrun tf tf_echo turtle1 turtle2
可观察到实时姿态,包括位置信息和旋转信息
3、利用rviz可视化工具观察坐标变换
rosrun rviz rviz -d ‘rospack find turtle_tf’/rviz/turtle_rviz.rviz
文章图片
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文件中的根元素采用标签定义
启动节点
文章图片
pkg:节点所在功能包名称
type:节点的可执行文件名称
name:节点运行时的名称
output:打印节点日志信息到当前终端
respawn:控制节点挂掉自动重启
required:某个节点必须启动
ns:命名空间,避免命名冲突
args:给节点输入参数
参数设置
文章图片
文章图片
重映射
文章图片
嵌套
文章图片
Rviz 【ROS学习(二)基础功能包】
文章图片