如何用URDF文件构建机械手模型并与MoveIt集成
机械手URDF文件的编写
我们用urdf文件来描述我们的机械手的外观以及物理性能。这里为了简便,就只用了基本的圆柱、立方体了。追求美观的朋友,还可以用dae文件来描述机械手的外形。
import re
def remove_comments(text):pattern = r'<!--(.*?)-->'return re.sub(pattern, '', text, flags=re.DOTALL)
文件six_arm.urdf
<?xml version="1.0"?>
<robot name="six_arm"><!-- Base link --><link name="base_link"><visual><geometry><box size="0.1 0.1 0.1"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="blue"><color rgba="0 0 1.0 1"/></material></visual><collision><geometry><box size="0.1 0.1 0.1"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="10"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Link 1 --><link name="link1"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="green"><color rgba="0 0.8 0 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 1: rotation around X-axis --><joint name="joint1" type="continuous"><parent link="base_link"/><child link="link1"/><axis xyz="0 0 1"/><origin xyz="0 0 0.1" rpy="0 0 0"/></joint><!-- Link 2 --><link name="link2"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="red"><color rgba="0.8 0 0 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 2: rotation around Y-axis --><joint name="joint2" type="continuous"><parent link="link1"/><child link="link2"/><axis xyz="1 0 0"/><origin xyz="0 0 0.1"/></joint><!-- Link 3 --><link name="link3"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="yellow"><color rgba="0.8 0.8 0 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 3: rotation around x-axis --><joint name="joint3" type="continuous"><parent link="link2"/><child link="link3"/><axis xyz="1 0 0"/><origin xyz="0 0 0.1"/></joint><!-- Link 4 --><link name="link4"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="green"><color rgba="0 0.8 0 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 4: rotation around X-axis --><joint name="joint4" type="continuous"><parent link="link3"/><child link="link4"/><axis xyz="0 1 0"/><origin xyz="0 0 0.1"/></joint><!-- Link 5 --><link name="link5"><visual><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/><material name="purple"><color rgba="0.8 0 0.8 1"/></material></visual><collision><geometry><cylinder length="0.1" radius="0.03"/></geometry><origin rpy="0 0 0" xyz="0 0 0.05"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 5: rotation around Y-axis --><joint name="joint5" type="continuous"><parent link="link4"/><child link="link5"/><axis xyz="1 0 0"/><origin xyz="0 0 0.1"/></joint><!-- Link 6 --><link name="link6"><visual><geometry><box size="0.1 0.1 0.2"/></geometry><origin rpy="0 0 0" xyz="0 0 0.1"/><material name="pink"><color rgba="0.8 0.4 0.8 1"/></material></visual><collision><geometry><box size="0.1 0.1 0.2"/></geometry><origin rpy="0 0 0" xyz="0 0 0.1"/></collision><inertial><mass value="0.2"/><inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/></inertial></link><!-- Joint 6: rotation around Z-axis --><joint name="joint6" type="continuous"><parent link="link5"/><child link="link6"/><axis xyz="0 0 1"/><origin xyz="0 0 0.1"/></joint><!-- Used for fixing robot to Gazebo 'base_link' 将机械手的基座固定在世界坐标上--><link name="world"/><joint name="fixed" type="fixed"><parent link="world"/><child link="base_link"/></joint><gazebo reference="base_link"><material>Gazebo/Black</material><gravity>true</gravity><selfCollide>false</selfCollide></gazebo><gazebo reference="link1"><material>Gazebo/Gray</material><selfCollide>false</selfCollide></gazebo><gazebo reference="link2"><material>Gazebo/Red</material><selfCollide>false</selfCollide></gazebo><gazebo reference="link3"><material>Gazebo/Blue</material></gazebo><gazebo reference="link4"><material>Gazebo/Green</material></gazebo><gazebo reference="link5"><material>Gazebo/Yellow</material></gazebo><gazebo reference="link6"><material>Gazebo/Orange</material></gazebo><!-- 在运行demo.launch.py时,需要注释这个ros2_control节点,因为它使用了xxx.ros2_control.xacro来生成了ros2_control节点--><ros2_control name="GazeboSystem" type="system"><hardware><plugin>gazebo_ros2_control/GazeboSystem</plugin></hardware><joint name="joint1"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint2"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint3"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint4"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint5"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint><joint name="joint6"><command_interface name="position"><param name="min">-1</param><param name="max">1</param></command_interface><state_interface name="position"><param name="initial_value">0.0</param></state_interface><state_interface name="velocity"/></joint></ros2_control><gazebo><plugin filename="libgazebo_ros2_control.so" name="gazebo_ros2_control"><parameters>$(find mybot)/config/ros2_controllers.yaml</parameters><robot_param_node>robot_state_publisher</robot_param_node></plugin></gazebo></robot>
机械手的外型
可以在vscode中打开这个文件然后用插件就可以看到这个机械手的外形。

有同学不知道如何在vscode中查看urdf模型,这里介绍一下: 先安装vscode的ROS拓展,

然后可以在urdf文件中右键–》command palette–》ROS:Preview URDF


机械手link的inertial的设置
真正设置的话,有公式,自己可以参考一下。
urdf里面的link必须要有旋转惯量矩阵‘intertial’的,否则在gazebo里面导入模型urdf时,会报下面的错。
[gazebo-1] [Err] [Model.cc:123] Error Code 23 Msg: FrameAttachedToGraph error, Non-LINK vertex with name [model] is disconnected; it should have 1 outgoing edge in MODEL attached_to graph.
ros2_control插件
该插件是在gazbo导入该模型文件时,创建与Ros2交互的接口。

上面这个是之前的,我现在更新成这样了主要是parameter节点不一样。用了$(find mybot)就方便一点。但是相应地launch文件中就要用xacro了。

上面的ros2_controllers.yaml文件是在下一步创建出来的,先不用管。
同时,ros2_control这个节点下的内容也是要和ros2_controllers.yaml对应的,也可以先不管。
这个节点在开始阶段先注释掉,否则会与通过moveit_setup_assistant创建的一个 fake_system 的 ros2_control冲突。

机械手与MoveIt的关联
通过前面的操作,我们拥有了一个描述机械手的文件 six_arm.urdf,接下来我们利用该文件创建一个可以利用MoveIt进行路径规划的“工程”。
建立一个文件夹myRobot,然后再在此文件夹中建立一个src文件夹

然后进入src文件夹路径,创建包
ros2 pkg create mybot_description --build-type ament_python

在 src/mybot_description文件夹下,创建urdf文件夹,然后把six_arm.urdf放进去,如下图所示。

返回myRobot目录,然后编译一下
colcon build

from setuptools import setupfrom glob import glob #这里
import os #这里package_name = 'mybot_description'setup(name=package_name,version='0.0.0',packages=[package_name],data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),(os.path.join('share', package_name, 'urdf'), glob('urdf/**')), #这里],install_requires=['setuptools'],zip_safe=True,maintainer='yong',maintainer_email='yong@todo.todo',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts': [],},
)
最后启动一下

相关文章:
如何用URDF文件构建机械手模型并与MoveIt集成
机械手URDF文件的编写 我们用urdf文件来描述我们的机械手的外观以及物理性能。这里为了简便,就只用了基本的圆柱、立方体了。追求美观的朋友,还可以用dae文件来描述机械手的外形。 import re def remove_comments(text):pattern r<!--(.*?)-->…...
uv pip install -r requirements.txt-报错,python版本过低
升级Python版本(推荐) browser-use0.1.40 需要 Python ≥3.11,但你的环境是 Python 3.10.12。升级Python版本是最直接的解决方案: 安装Python 3.11: 使用 pyenv(Linux/macOS):pyenv…...
【训练细节解读】文本智能混合分块(Mixtures of Text Chunking,MoC)引领RAG进入多粒度感知智能分块阶段
喜欢本文可以在主页订阅专栏哟 核心创新:双重评估指标与混合分块架构: 第一章:检索增强生成(RAG)技术演进与分块挑战 1.1 RAG架构的核心演变 检索增强生成(Retrieval-Augmented Generation)…...
招聘信息|基于SprinBoot+vue的招聘信息管理系统(源码+数据库+文档)
招聘信息管理系统 目录 基于SprinBootvue的招聘信息管理系统 一、前言 二、系统设计 三、系统功能设计 5.1系统功能模块 5.2管理员功能模块 5.3企业后台管理模块 5.4用户后台管理模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、…...
HCIA-AI人工智能笔记1:大模型技术演进与发展历程
一、大模型发展的技术演进图谱 timelinetitle 大模型发展关键里程碑1958 : 感知机模型诞生(Frank Rosenblatt)1986 : BP反向传播算法(Rumelhart)2012 : AlexNet开启深度学习时代2017 : Transformer架构提出(《Attenti…...
躲藏博弈中的策略优化:整合历史数据、概率论与博弈论
躲藏博弈中的策略优化:整合历史数据、概率论与博弈论 一、引言 躲藏博弈(Hiding Games)作为一类特殊的博弈模型,广泛存在于军事对抗、网络安全、商业竞争甚至日常生活中。其核心在于一方(躲藏者)试图避免被另一方(寻找者)发现,双方各自选择…...
C语言,记录一次局部变量被意外修改的问题
背景:单片机开发过程中,我在函数体内(begin_face_record)定义了一个局部变量data_length,在使用的时候,该局部变量一直别改变,每次调用其他函数,例如c库里面的函数memcpy,不知什么情况data_length值就会被改变。 1、源码分析 void main(void) { init_gpio();init_fa…...
机器学习——正则化、欠拟合、过拟合、学习曲线
过拟合(overfitting):模型只能拟合训练数据的状态。即过度训练。 避免过拟合的几种方法: ①增加全部训练数据的数量(最为有效的方式) ②使用简单的模型(简单的模型学不够,复杂的模型学的太多&am…...
在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别
在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别。 1. picker 的特点 描述: picker 是微信小程序中的原生组件,通常用于选择单项或多项值,如时…...
向量数据库对比以及Chroma操作
一、向量数据库与传统类型数据库 向量数据库(Vector Storage Engine)与传统类型的数据库如关系型数据库(MySQL)、文档型数据库(MongoDB)、键值存储(Redis)、全文搜索引擎࿰…...
Python Matplotlib面试题精选及参考答案
绘制函数 y2x5 在区间 [1,10] 的折线图,设置标题和坐标轴标签 要绘制函数 y 2x 5 在区间 [1, 10] 的折线图,并设置标题和坐标轴标签,可借助 Python 的 matplotlib 库来实现。以下是详细的实现步骤与代码示例。 首先,要导入 mat…...
FiddlerScript学习笔记
参考官方文档:https://www.fiddlerbook.com/fiddler/dev/scriptsamples.asp json // 反序列化 static function jsonDecode(str : String){return Fiddler.WebFormats.JSON.JsonDecode(str).JSONObject; } // 序列化 static function jsonEncode(jsonObject : Obje…...
正点原子[第三期]Arm(iMX6U)Linux移植学习笔记-5.1 uboot顶层Makefile分析-VSCode工程创建
前言: 本文是根据哔哩哔哩网站上“Arm(iMX6U)Linux系统移植和根文件系统构键篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。 引用: …...
Linux内核IPoIB驱动中的RSS队列选择机制分析
摘要 本文深入分析了Linux内核中InfiniBand over Ethernet(IPoIB)驱动程序的发送队列选择函数ipoib_select_queue_sw_rss的实现。该函数通过复杂的条件编译和逻辑分支,实现了基于软件的接收端扩展(RSS)功能,确保网络流量在多队列环境下的高效分发,提升网络性能和吞吐量…...
js数组遍历十种方法
在JavaScript中,数组遍历可以有多种方法。以下列举了10种常用的数组遍历方式: For 循环 let array [1, 2, 3, 4, 5]; for (let i 0; i < array.length; i) {console.log(array[i]); }For-of 循环(ES6) let array [1, 2, 3, …...
OTP单片机调试工具之—单线数据编码
OTP单片机调试工具在实现过程中离不开单线数据的传输,那么使用哪一种方式的数据编码会比较好呢? 我所了解的主要有以下三种: 1.UART(串口),这种方式在单片机和pc之间进行传输都非常常见,效率比较…...
SWPU 2022 新生赛
webdog1__start if (isset($_GET[web])) {$first$_GET[web];if ($firstmd5($first)) md5 自等 web0e215962017 (md5后也是 0e) 登入后得到提示,robots.txt 访问 f14g.php 返回包里发现 hint > if (isset($_GET[get])){$get$_GET[get];if(!strs…...
Java 基础到进阶企业技巧(二)
在 Java 学习的旅程中,我们逐步探索了其丰富的知识体系,从基础的数据类型、字符串操作,到流程控制、运算符的运用,每一步都为我们构建强大的编程能力奠定基石。同时,了解这些知识在 Java 全栈开发中的应用场景…...
【后端】【django】【related_name】`related_name` 的作用
related_name 的作用 related_name 用于 Django 的 ForeignKey 和 OneToOneField,用于 反向访问 关联模型的数据。 默认情况下,Django 会自动生成一个反向关系的名字,但如果多个外键指向同一个模型,就可能发生命名冲突。related…...
Deepseek-R1大模型微调实战技术深度解析
一、Deepseek-R1架构特性与微调适配性分析 1.1 核心架构创新对微调的影响 Deepseek-R1基于Deepseek-V3-Base架构,通过MoE(Mixture-of-Experts)与MLA(Multi-Head Latent Attention)的协同设计,实现了参数规模与计算效率的平衡。其6710亿参数总量中,每个token仅激活37B参…...
Google最新生图模型Gemini-2.0-Flash-Exp免费用
Google发布新生图模型 Google释放出最新生图模型,在发布说明中提到: 2025年3月12日 在 Gemini-2.0-Flash-Exp 中发布原生图像输出功能 Gemini 2.0 Flash Experimental 模型发布,支持原生图像输出功能。开发者能够使用 Gemini 进行图像输出和…...
leecode695.岛屿的最大面积
跟求岛屿数量的题目差不多,依旧是深度搜索或者广度搜索问题 class Solution { private:int maxAreaOfIsland(vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y){if(x<0||x>grid.size()||y<0||y>…...
助力字体管理,规避设计卡顿的得力工具
在设计领域,字体看似平常,却常常在关键时刻“掉链子”,让设计师们头疼不已。面对海量字体库,找到心仪那款宛如大海捞针,字体安装过多还会造成软件卡顿,这些麻烦事儿,频繁与字体打交道的朋友肯定…...
零基础上手Python数据分析 (4):Python数据结构精讲 - 列表、元组、字典、集合
写在前面 回顾一下,在之前的博客中,我们学习了 Python 的基本数据类型(数值、字符串、布尔值)和核心语法(运算符、变量、流程控制、函数、模块)。 现在,我们已经掌握了 Python 编程的基础知识。 接下来,我们将进入数据分析的关键环节: 数据组织。 在数据分析中,数据…...
数统院复试来啦,西电数学与统计学院—考研录取情况
4西安电子科技大学—数学与统计学院—考研录取统计 01、数学与统计学院各个方向 02、24数学与统计学院近三年复试分数线对比 数统院24年院线相对于23年院线增加高达30分,确实增长浮动比较高,接近30分的水平,因此大家更需要好好去努力…...
Windows功能之FTP服务器搭建
一、创作背景 之前有用linux系统搭建过ftp服务器,最近想着用windows系统也顺便搭建一个,看网上有第三方服务软件一键部署,记得windows可以不借助第三方软件就可以搭建,就想顺便操作试试,结果老是连接不上,费…...
leetcode hot100普通动态规划/基础DP
1️⃣1️⃣ 普通动态规划(基础 DP) 70. 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 题解: 动态规划Dynamic Programming ,在观察动态中找到如何规划解题的步骤…...
基于Python的天气预报数据可视化分析系统-Flask+html
开发语言:Python框架:flaskPython版本:python3.8数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 系统登录 可视化界面 天气地图 天气分析 历史天气 用户管理 摘要 本文介绍了基于大数据…...
【鸿蒙开发】Hi3861学习笔记-Visual Studio Code安装(New)
00. 目录 文章目录 00. 目录01. Visual Studio Code概述02. Visual Studio Code下载03. Visual Studio Code安装04. Visual Studio Code插件05. 附录 01. Visual Studio Code概述 vscode是一种简化且高效的代码编辑器,同时支持诸如调试,任务执行和版本管…...
git报错:“fatal:refusing to merge unrelated histories“
新建仓库,克隆本地项目到新仓库,首次同步本地已提交的代码到远程时,报错:"fatal:refusing to merge unrelated histories" 。 报错意思是:致命的:拒绝合并无关的历史。 一、问题背景ÿ…...
