百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

《ROS入门》第12讲ROS中的坐标系管理系统

toyiye 2024-06-28 09:54 15 浏览 0 评论

TF功能包能干什么?

  • ? 五秒钟之前,机器人头部坐标系相对于全局坐
  • 标系的关系是什么样的?
  • ? 机器人夹取的物体相对于机器人中心坐标系的
  • 位置在哪里?
  • ? 机器人中心坐标系相对于全局坐标系的位置在
  • 哪里?
  • TF坐标变换如何实现?

  • ? 广播TF变换
  • ? 监听TF变换
  • 备注:具体坐标变换的理论公式推导参考《机器人学导论》

    初体验:

    在终端启动海龟的TF坐标变换的例程,步骤:

    第一,安装TF功能包:

    sudo apt-get install ros-版本号-turtle-tf

    (我使用的是noetic,自带TF功能包)

    第二步,使用roslaunch启动

    roslaunch turtle_tf2 turtle_tf2_demo_cpp.launch 

    第三步,启动海龟键盘节点

    rosrun turtlesim turtle_teleop_key 

    然后使用键盘的上下左右键操作即可看到现象

    tf坐标系广播与监听的编程实现

    1,创建功能包

    $ cd ~/catkin_ws/src
    $ catkin_create_pkg doubi roscpp rospy tf turtlesim
    $ cd ~/catkin_ws/src
    $ catkin_make

    2,编写程序

    如何实现一个tf广播器

    • ?定义TF广播器(TransformBroadcaster)
    • ?创建坐标变换值;
    • ?发布坐标变换(sendTransform)
    /**
     * 该例程产生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)
    {
    	// 创建tf的广播器
    	static tf::TransformBroadcaster br;
    
    	// 初始化tf数据
    	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);
    
    	// 广播world与海龟坐标系之间的tf数据
    	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];
    
    	// 订阅海龟的位姿话题
    	ros::NodeHandle node;
    	ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback);
    
        // 循环等待回调函数
    	ros::spin();
    
    	return 0;
    };
    

    如何实现一个TF监听器

    • ?定义TF监听器;
    • ?查找坐标变换;
    /**
     * 该例程监听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节点
    	ros::init(argc, argv, "my_tf_listener");
    
        // 创建节点句柄
    	ros::NodeHandle node;
    
    	// 请求产生turtle2
    	ros::service::waitForService("/spawn");
    	ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");
    	turtlesim::Spawn srv;
    	add_turtle.call(srv);
    
    	// 创建发布turtle2速度控制指令的发布者
    	ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel", 10);
    
    	// 创建tf的监听器
    	tf::TransformListener listener;
    
    	ros::Rate rate(10.0);
    	while (node.ok())
    	{
    		// 获取turtle1与turtle2坐标系之间的tf数据
    		tf::StampedTransform transform;
    		try
    		{
    			listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0));
    			listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);
    		}
    		catch (tf2::TransformException &ex) 
    		{
    			ROS_ERROR("%s",ex.what());
    			ros::Duration(1.0).sleep();
    			continue;
    		}
    
    		// 根据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;
    };
    

    3,编译并测试

    $ cd ~/catkin_ws
    $ catkin_make
    $ source devel/setup.bash
    $ roscore
    $ rosrun turtlesim turtlesim_node
    $ rosrun doubi turtle_tf_broadcaster __name:=turtle1_tf_broadcaster /turtle1
    $ rosrun doubi turtle_tf_broadcaster __name:=turtle2_tf_broadcaster /turtle2
    $ rosrun doubi turtle_tf_listener
    $ rosrun turtlesim turtle_teleop_key

    相关推荐

    为何越来越多的编程语言使用JSON(为什么编程)

    JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

    何时在数据库中使用 JSON(数据库用json格式存储)

    在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

    MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

    前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

    JSON对象花样进阶(json格式对象)

    一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

    深入理解 JSON 和 Form-data(json和formdata提交区别)

    在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

    JSON 语法(json 语法 priority)

    JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

    JSON语法详解(json的语法规则)

    JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

    MySQL JSON数据类型操作(mysql的json)

    概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

    JSON的数据模式(json数据格式示例)

    像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

    前端学习——JSON格式详解(后端json格式)

    JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

    什么是 JSON:详解 JSON 及其优势(什么叫json)

    现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

    PostgreSQL JSON 类型:处理结构化数据

    PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

    JavaScript:JSON、三种包装类(javascript 包)

    JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

    Python数据分析 只要1分钟 教你玩转JSON 全程干货

    Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

    比较一下JSON与XML两种数据格式?(json和xml哪个好)

    JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

    取消回复欢迎 发表评论:

    请填写验证码