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

前言

        本篇将完成一个行走的机器人,并以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, TransformStampedclass 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.0loop_rate = self.create_rate(30)# robot statetilt = 0.tinc = degreeswivel = 0.angle = 0.height = 0.hinc = 0.005# message declarationsodom_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_statenow = 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)*2odom_trans.transform.translation.y = sin(angle)*2odom_trans.transform.translation.z = 0.7odom_trans.transform.rotation = \euler_to_quaternion(0, 0, angle + pi/2) # roll,pitch,yaw# send the joint state and transformself.joint_pub.publish(joint_state)self.broadcaster.sendTransform(odom_trans)# Create new robot statetilt += tincif tilt < -0.5 or tilt > 0.0:tinc *= -1height += hincif height > 0.2 or height < 0.0:hinc *= -1swivel += degreeangle += degree/4# This will adjust as needed per iterationloop_rate.sleep()except KeyboardInterrupt:passdef 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 Nodedef 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.mzph.cn/diannao/12947.shtml

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

相关文章

醉了,面个功能测试,还问我Python装饰器

Python 装饰器是个强大的工具&#xff0c;可帮你生成整洁、可重用和可维护的代码。某种意义上说&#xff0c;会不会用装饰器是区分新手和老鸟的重要标志。如果你不熟悉装饰器&#xff0c;你可以将它们视为将函数作为输入并在不改变其主要用途的情况下扩展其功能的函数。装饰器可…

dhcp(接口和全局地址池模式)

接口地址池和全局地址池 dhcp应用 1.全部开启dhcp功能 2.ar5 0口接口地址池 1口全局地址池 3.ar6和ar7配置&#xff0c;查看能否自动获取ip 左右不同两个网络&#xff0c;接口和全局地址池的区别 部分截图 ar6 ar7 ar5

(实测验证)【移远EC800M-CN 】TCP 透传

引言 本文章使用自研“超小体积TTL转4GGPS集成模块”进行实测验证&#xff1b; 1、配置移远EC800M-CN TCP 透传 串口助手发送&#xff1a; ATQIOPEN1,0,"TCP","36.137.226.30",39755,0,2 //配置服务器地址和端口号&#xff1b; 4G模组返回…

07-Fortran基础--Fortran指针(Pointer)的使用

07-Fortran基础--Fortran指针Pointer的使用 0 引言1 指针&#xff08;Poionter&#xff09;的有关内容1.1 一般类型指针1.2 数组指针1.3 派生类(type)指针1.4 函数指针 2 可运行code 0 引言 Fortran是一种广泛使用的编程语言&#xff0c;特别适合科学计算和数值分析。Fortran 9…

java代码混淆工具ProGuard混淆插件

java代码混淆工具ProGuard混淆插件 介绍 ProGuard是一个纯java编写的混淆工具&#xff0c;有客户端跟jar包两种使用方式。可以将程序打包为jar&#xff0c;然后用工具进行混淆&#xff0c;也可以在maven中导入ProGuard的插件&#xff0c;对代码进行混淆。 大家都知道 java代…

[ciscn 2022 东北赛区]math

1.题目 import gmpy2 from Crypto.Util.number import * from flag import flag assert flag.startswith(b"flag{") assert flag.endswith(b"}") messagebytes_to_long(flag) def keygen(nbit, dbit):if 2*dbit < nbit:while True:a1 getRandomNBitIn…

编辑器目录树的设计,一点也不简单

朋友们好&#xff0c;我是优秀的大鹏 今天花了很长时间思考一个网页文档编辑器&#xff0c;云端目录树要怎么设计 这个看似简单的需求&#xff0c;技术上和产品上的思考却非常复杂 下面以几种编辑器为例&#xff0c;讲一下各种编辑器在技术上和产品的思考 1、以Vscode为代表的本…

【神经网络与深度学习】Transformer原理

transformer ENCODER 输入部分 对拆分后的语句x [batch_size, seq_len]进行以下操作 Embedding 将离散的输入&#xff08;如单词索引或其他类别特征&#xff09;转换为稠密的实数向量&#xff0c;以便可以在神经网络中使用。位置编码 与RNN相比&#xff0c;RNN是一个字一个字…

Django Rest Framework 全局异常处理

在Django Rest Framework&#xff08;DRF&#xff09;中&#xff0c;全局异常处理是一种重要的机制&#xff0c;它可以帮助我们更好地管理API中的异常情况&#xff0c;并返回统一的错误响应。本文将详细介绍两种全局异常处理的方法&#xff1a;使用中间件&#xff08;Middlewar…

机器学习(3)

目录 3-1线性回归 3-2最小二乘解 3-3多元线性回归 3-4广义线性模型 3-5对率回归 3-6对率回归求解 3-7线性判别分析 3-8LDA的多类推广 3-9多分类学习基本思路 3-10类别不平衡 3-1线性回归 线性模型为什么重要&#xff1f; 人类在考虑问题时&#xff0c;通常…

先有JVM还是先有垃圾回收器?很多人弄混淆了

是先有垃圾回收器再有JVM呢&#xff0c;还是先有JVM再有垃圾回收器呢&#xff1f;或者是先有垃圾回收再有JVM呢&#xff1f;历史上还真是垃圾回收更早面世&#xff0c;垃圾回收最早起源于1960年诞生的LISP语言&#xff0c;Java只是支持垃圾回收的其中一种。下面我们就来刨析刨析…

抖店商品详情API接口(产品参数|详情图)

抖店商品详情API接口(产品参数|详情图) 参数仅供参考&#xff1a; {"code": 0,"msg": "调用成功","time": "1715763239","data": {"properties": [{"format": [{"message": [{&q…

C语言简要(一)

总得让她开心吧 helloworld #include <stdio.h>int main() {printf("hello world!\n");return 0; } 程序框架 #include <stdio.h> int main {return 0; }输出 printf("hello world!\n"); "里面的内容叫做“字符串”&#xff0c;prin…

BUUCTF靶场[MISC]wireshark、被嗅探的流量、神秘龙卷风、另一个世界

[misc]wireshark 考点&#xff1a;流量、追踪流 工具&#xff1a;wireshark 先看题目&#xff0c;管理员密码 将下载的文件用wireshark打开&#xff0c;查找flag 点击追踪tcp流&#xff0c;开始挨个查看flag [misc]被嗅探的流量 考点&#xff1a;流量、追踪流 工具&#xf…

武汉星起航:亚马逊构建综合性商业生态,卖家买家共享全球化红利

在当今全球化日益加速的时代&#xff0c;亚马逊不仅以其卓越的电商平台服务全球消费者&#xff0c;更通过一系列前沿服务打造了一个综合性的商业生态系统。在这个生态系统中&#xff0c;卖家能够轻松拓展全球业务&#xff0c;买家则享受到了前所未有的购物体验。亚马逊以其独特…

FreeRTOS【6】线程优先级

1.开发背景 基于上一篇指引&#xff0c;已经了解了线程的阻塞&#xff0c;这个篇章主要介绍线程优先级的影响 2.开发需求 设计实验验证高优先级会抢占低优先级线程 CPU 3.开发环境 window10 MDK STM32F429 FreeRTOS10.3.1 4.实现步骤 1&#xff09;创建测试线程&#xff…

测试之路 - 精准而优雅

引子 这几年业内一直在做精准测试&#xff0c;大都使用工具 diff 代码改动、分析代码覆盖率这些平台集成的能力。 业务测试中&#xff0c;我们在技术设计和代码实现的基础上也做了一些精减和精准的测试实践&#xff0c;通过深入测试有针对的设计 case&#xff0c;发现隐藏问题…

抖音小程序使用Vant

安装 Vant 有针对小程序的版本&#xff0c;通过npm安装&#xff1a; npm i vant/weapp -S --production构建 npm 安装 Vant Weapp 后需要构建 NPM&#xff0c;在菜单的【工具】选项中选择【构建 NPM】&#xff1a; 使用组件 抖音小程序和微信小程序还是有一些差别的&#x…

怎么把3d模型导出cad立面---模大狮模型网

在设计工作中&#xff0c;将3D模型导出到CAD软件并生成立面图是一项常见但关键的任务。这不仅有助于更好地展示设计方案&#xff0c;还能方便后续的工程制图和施工。本文将介绍如何通过3ds Max软件将3D模型导出到CAD软件&#xff0c;并生成高质量的立面图&#xff0c;为您提供实…

现货正泰漏电小型断路器NXB-32LE-C16 30MA1P+N原装正品NXB-40L

品牌&#xff1a;CHNT/正泰 型号&#xff1a;NXBLE 额定电流&#xff1a;25A,16A,20A,40A,32A 漏电保护器类型&#xff1a;2P 产地&#xff1a;中国大陆 电压&#xff1a;1000V及以下 极数&#xff1a;3P,4p,2P,1PN 电源方式&#xff1a;交流电 3C证书编号&#xff1a;…