ROS 2边学边练(48)-- 将URDF与robot_state_publisher一起使用

news2024/11/22 22:16:41

前言

        本篇将完成一个行走的机器人,并以tf2消息的方式实时发布机器人状态,以便我们在Rviz中同步查看。

        首先,我们创建描述机器人装配的URDF模型。接下来,我们编写一个节点,用于模拟运动并发布JointState和位姿变换。然后,我们使用robot_state_publisher将整个robot状态发布到/tf2。

动动手

创建新包

        执行如下命令创建新的工作空间second_ros2_ws,并在其下创建src文件夹:

$mkdir -p second_ros2_ws/src

        再在src下创建urdf_tutorial_r2d2包:

$cd second_ros2_ws/src
$ros2 pkg create --build-type ament_python --license Apache-2.0 urdf_tutorial_r2d2 --dependencies rclpy
$cd urdf_tutorial_r2d2

创建URDF文件

        在urdf_tutorial_r2d2包根路径下,创建urdf文件夹,以放置保存一些组件:

$mkdir -p urdf

        分别下载URDF文件(r2d2.urdf.xml)和Rviz配置文件(r2d2.rviz)到second_ros2_ws/src/urdf_tutorial_r2d2/urdf/路径下。

发布状态

        现在我们需要一种方法来指定机器人的状态。要做到这一点,我们必须指定所有三个关节和整体里程计。

        创建second_ros2_ws/src/urdf_tutorial_r2d2/urdf_tutorial_r2d2/state_publisher.py文件,将下述内容复制其中:

from math import sin, cos, pi
import rclpy
from rclpy.node import Node
from rclpy.qos import QoSProfile
from geometry_msgs.msg import Quaternion
from sensor_msgs.msg import JointState
from tf2_ros import TransformBroadcaster, TransformStamped

class StatePublisher(Node):

    def __init__(self):
        rclpy.init()
        super().__init__('state_publisher')

        qos_profile = QoSProfile(depth=10)
        self.joint_pub = self.create_publisher(JointState, 'joint_states', qos_profile)
        self.broadcaster = TransformBroadcaster(self, qos=qos_profile)
        self.nodeName = self.get_name()
        self.get_logger().info("{0} started".format(self.nodeName))

        degree = pi / 180.0
        loop_rate = self.create_rate(30)

        # robot state
        tilt = 0.
        tinc = degree
        swivel = 0.
        angle = 0.
        height = 0.
        hinc = 0.005

        # message declarations
        odom_trans = TransformStamped()
        odom_trans.header.frame_id = 'odom'
        odom_trans.child_frame_id = 'axis'
        joint_state = JointState()

        try:
            while rclpy.ok():
                rclpy.spin_once(self)

                # update joint_state
                now = self.get_clock().now()
                joint_state.header.stamp = now.to_msg()
                joint_state.name = ['swivel', 'tilt', 'periscope']
                joint_state.position = [swivel, tilt, height]

                # update transform
                # (moving in a circle with radius=2)
                odom_trans.header.stamp = now.to_msg()
                odom_trans.transform.translation.x = cos(angle)*2
                odom_trans.transform.translation.y = sin(angle)*2
                odom_trans.transform.translation.z = 0.7
                odom_trans.transform.rotation = \
                    euler_to_quaternion(0, 0, angle + pi/2) # roll,pitch,yaw

                # send the joint state and transform
                self.joint_pub.publish(joint_state)
                self.broadcaster.sendTransform(odom_trans)

                # Create new robot state
                tilt += tinc
                if tilt < -0.5 or tilt > 0.0:
                    tinc *= -1
                height += hinc
                if height > 0.2 or height < 0.0:
                    hinc *= -1
                swivel += degree
                angle += degree/4

                # This will adjust as needed per iteration
                loop_rate.sleep()

        except KeyboardInterrupt:
            pass

def euler_to_quaternion(roll, pitch, yaw):
    qx = sin(roll/2) * cos(pitch/2) * cos(yaw/2) - cos(roll/2) * sin(pitch/2) * sin(yaw/2)
    qy = cos(roll/2) * sin(pitch/2) * cos(yaw/2) + sin(roll/2) * cos(pitch/2) * sin(yaw/2)
    qz = cos(roll/2) * cos(pitch/2) * sin(yaw/2) - sin(roll/2) * sin(pitch/2) * cos(yaw/2)
    qw = cos(roll/2) * cos(pitch/2) * cos(yaw/2) + sin(roll/2) * sin(pitch/2) * sin(yaw/2)
    return Quaternion(x=qx, y=qy, z=qz, w=qw)

def main():
    node = StatePublisher()

if __name__ == '__main__':
    main()

创建启动文件

        创建second_ros2_ws/src/urdf_tutorial_r2d2/launch文件夹,在其中新建demo_launch.py文件,将下面内容复制其中:

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node

def generate_launch_description():

    use_sim_time = LaunchConfiguration('use_sim_time', default='false')

    urdf_file_name = 'r2d2.urdf.xml'
    urdf = os.path.join(
        get_package_share_directory('urdf_tutorial_r2d2'),
        urdf_file_name)
    with open(urdf, 'r') as infp:
        robot_desc = infp.read()

    return LaunchDescription([
        DeclareLaunchArgument(
            'use_sim_time',
            default_value='false',
            description='Use simulation (Gazebo) clock if true'),
        Node(
            package='robot_state_publisher',
            executable='robot_state_publisher',
            name='robot_state_publisher',
            output='screen',
            parameters=[{'use_sim_time': use_sim_time, 'robot_description': robot_desc}],
            arguments=[urdf]),
        Node(
            package='urdf_tutorial_r2d2',
            executable='state_publisher',
            name='state_publisher',
            output='screen'),
    ])

编辑setup.py文件

        我们必须告诉colcon build工具如何安装指定的python包。这可以通过修改python包根路径下的setup.py文件实现。

        包含如下内容

import os
from glob import glob
from setuptools import setup
from setuptools import find_packages
data_files=[
  ...
  (os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*launch.[pxy][yma]*'))),
  (os.path.join('share', package_name), glob('urdf/*')),
],

        修改入口点(entry_points),使得可以通过控制台启动'state_publisher'.

'console_scripts': [
    'state_publisher = urdf_tutorial_r2d2.state_publisher:main'
],

安装python包

$cd second_ros2_ws
$colcon build --symlink-install --packages-select urdf_tutorial_r2d2

        最后配置下环境变量:

$source install/setup.bash

查看结果

$ros2 launch urdf_tutorial_r2d2 demo_launch.py

        打开另外一个终端,运行rviz2进行查看(rviz使用参考)。

$source /opt/ros/iron/setup.bash
$rviz2 -d second_ros2_ws/install/urdf_tutorial_r2d2/share/urdf_tutorial_r2d2/r2d2.rviz

        不出大意外的话,大家运行后的结果应该像下面这样(需要手动点击左下角的Add按钮添加TF及机器人模型),机器人“隐身”了。 

 

        如果我们换个命令,则一切正常了(其实前面的命令最后调用的还是下面这个路径的rviz文件)

$rviz2 -d src/urdf_tutorial_r2d2/urdf/r2d2.rviz

或加上绝对路径,

$rviz2 -d ~/Desktop/second_ros2_ws/install/urdf_tutorial_r2d2/share/urdf_tutorial_r2d2/r2d2.rviz

 

        此例原始代码工程在这(只不过编译运行后会报错误,需要增加dummpy link来解决)。

本篇完。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1679489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux进程概念总结

这里总结下Linux进程概念总结❗ 冯诺依曼&#xff1a; CPU 运算器与控制器RAM 内存&#xff08;存储器&#xff09;Cache 缓存&#xff08;一种技术&#xff09;不属于冯诺依曼体系结构。ROM 磁盘&#xff08;输入输出设备&#xff09;磁盘 既可以从硬盘读取数据也可以向硬盘…

AI绘画提示词案例(车

目录 1. 提示词1——复古敞篷车&#xff1a;2. 提示词2——霓虹城市&#xff1a;3. 提示词3——沙滩SUV&#xff1a;4. 网站推荐——LibLib小结&#xff1a; 1. 提示词1——复古敞篷车&#xff1a; 正向提示词&#xff1a; In the quiet suburbs,a vintage-style convertible…

《海峡科技与产业》是什么级别的期刊?是正规期刊吗?能评职称吗?

问题解答 问&#xff1a;《海峡科技与产业》期刊是什么级别&#xff1f; 答&#xff1a;国家级 主管单位&#xff1a;中华人民共和国科学技术部 主办单位&#xff1a;科技部海峡两岸科学技术交流中心 问&#xff1a;《海峡科技与产业》影响因子&#xff1f; 答&#xff1a;…

十大排序算法之->归并排序

一、归并排序简介 归并排序是一种基于分治策略的有效且稳定的排序算法。归并排序由约翰冯诺伊曼提出&#xff0c;是计算机科学中一个非常基础且历史悠久的算法。 归并排序利用分治法的策略&#xff0c;将一个大的数组拆分成几个小的子数组&#xff0c;这些子数组各自独立地排…

力扣82题删除排序链表中的重复元素

82题删除排序链表中的重复元素 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 题目分析 这个题需要返回已排序链表&#xff0c;我们需要考虑一种情况就是头结点为重复元素&…

43k Star!推荐一款功能强大的开源笔记软件!

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

dubbo复习:(3) 服务超时时间配置

在dubbo admin中 可以进行类似如下配置 configVersion: v2.7 enabled: true configs:- side: consumeraddresses:- 0.0.0.0parameters:timeout: 55这样配置之后&#xff0c;当服务端响应超过55毫秒时&#xff0c;在服务消费者的控制台就会看到超时信息

##21 深入理解文本处理:使用PyTorch进行NLP基础操作

文章目录 前言简介文本预处理实现分词构建词汇表 文本向量化构建简单的文本分类模型结论 前言 在现代深度学习应用中&#xff0c;文本处理是不可或缺的一部分&#xff0c;尤其在自然语言处理&#xff08;NLP&#xff09;领域。借助强大的框架如PyTorch&#xff0c;我们可以更加…

软件测试常见面试题合集(内附详细答案)

01 软件测试理论部分 1.1 测试概念 1. 请你分别介绍一下单元测试、集成测试、系统测试、验收测试、回归测试 单元测试&#xff1a;完成最小的软件设计单元&#xff08;模块&#xff09;的验证工作&#xff0c;目标是确保模块被正确的编码 集成测试&#xff1a;通过测试发现与…

【强化学习】DQN类算法的一些理解

一、DQN算法为什么要使用两个网络&#xff1f; DQN算法通常包含两个网络&#xff1a;一个是评估网络training_network&#xff0c;另一个是目标网络target_network。这两个网络的结构和初始权重是相同的&#xff0c;但它们的权重是不同步更新的。使用两个网络的原因是为了稳定…

【数组中重复的数据】leetcode,python

和上题一样&#xff0c;【找到所有数组中消失的数字】 换个判断条件就行 class Solution:def findDuplicates(self, nums: List[int]) -> List[int]:nlen(nums)for i in nums:x(i-1)%nnums[x]n#只需要替换条件即可return [i1 for i,num in enumerate(nums) if num>(2*n)…

easyx快速入门1

1.基本说明 EasyX 是针对 C 的图形库&#xff0c;可以帮助 C/C 初学者快速上手图形和游戏编程。 比如&#xff0c;可以基于 EasyX 图形库很快的用几何图形画一个房子&#xff0c;或者一辆移动的小车&#xff0c;可以编写俄罗斯方块、贪吃蛇、黑白棋等小游戏&#xff0c;可以练…

公共命名空间和RHP

概述 RHP的全称是&#xff1a;the little Robot that Helped me Program&#xff0c;帮我编程序的小机器人。 RHP必然存在&#xff0c;C语言的宏、C的模板&#xff0c;都是RHP&#xff1b;更复杂的例子&#xff0c;是lex和yacc&#xff0c;它们是制作程序的程序&#xff0c;也…

YOLOv9训练自己的数据集:最新最详细教程

一、代码及论文链接&#xff1a; 代码链接&#xff1a;https://github.com/WongKinYiu/yolov9/tree/main 论文链接&#xff1a;https://arxiv.org/abs/2402.13616 二、使用步骤 1.1 虚拟环境配置 创建一个虚拟环境用于单独对yolov9的环境进行配置&#xff1a; conda crea…

Latex问题1

问题 添加bib文件的引用后 \bibliographystyle{IEEEtran} \bibliography{IEEEabrv}之后&#xff0c;出现莫名其妙的错误&#xff0c;如下 IEEEabrv.bib是我的参考文献的bib文件&#xff0c;CCS_1.tex是我的tex文件&#xff0c;bib文件中的内容为 ARTICLE{1,author{Capponi,…

冥想训练具体方法有哪些|流静冥想

冥想是一种身体的放松和敏锐的警觉性相结合的状态。 每日练习的好处远不止你花在集中注意力的那几分钟。桑托雷利是建在乌斯特的马萨诸塞大学医学院的减压诊所的所长&#xff0c;她也是《自愈》的作者&#xff0c;她说&#xff1a;"冥想是一种工具&#xff0c;通过练习&a…

Python使用asyncio包实现异步编程

1. 异步编程 异步编程是一种编程范式&#xff0c;用于处理程序中需要等待异步操作完成后才能继续执行的情况。异步编程允许程序在执行耗时的操作时不被阻塞&#xff0c;而是在等待操作完成时继续执行其他任务。这对于处理诸如文件 I/O、网络请求、定时器等需要等待的操作非常有…

如何隐藏计算机IP地址,保证隐私安全?

隐藏计算机的IP地址在互联网在线活动种可以保护个人隐私&#xff0c;这是在线活动的一种常见做法&#xff0c;包括隐私问题、安全性和访问限制内容等场景。那么如何做到呢?有很5种方法分享。每种方法都有自己的优点和缺点。 1. 虚拟网络 当您连接到虚拟服务器时&#xff0c;您…

干什么副业好呢?

选择适合自己的副业可以根据个人的兴趣、技能和时间来决定。以下是一些常见的副业选择 1. 在线销售 可以在电商平台上开设自己的网店&#xff0c;销售自己感兴趣的产品&#xff0c;如手工艺品、服装、配饰等。 2. 做任务 网上我还在做的致米宝库&#xff0c;一个月有个一千多…

【go项目01_学习记录12】

代码组织 1 代码结构2 重构与测试2.1 安装测试功能2.2 testify 的常用断言函数 3 表组测试 1 代码结构 所有的代码写在一个main.go文件里面&#xff0c;GO编译器也是可以正常执行的。但是当代码量很庞大时&#xff0c;很难进行维护。 Go Web 程序的代码组织 单文件——反模式…