温故知新,机器人进化论之系统操作系统(ROS)与统一机器人描述格式URDF、Xacro

什么是ROS

image

ROS(Robot Operating System)是一种广泛使用的开源机器人操作系统,它为机器人应用开发提供了基础架构和工具。尽管名字中包含"操作系统"(Operating System),但ROS其实并不是一个传统意义上的操作系统。它是一个集成的框架,帮助开发者创建机器人应用程序。

消息传递和通信

ROS提供了一个强大的通信架构,允许不同的机器人组件(如传感器、控制器、执行器等)进行信息交换。它使用发布/订阅和客户端/服务端模型来实现节点之间的通信。

通过roscore启动中心化的消息传递系统,节点可以在系统中发送、接收消息或调用服务。

节点和包(Packages)

ROS系统由多个“节点”组成。每个节点是一个独立的进程,执行机器人特定任务(例如控制、感知、运动规划等)。

所有的节点都组织在包(Package)中。每个包包含相关的代码、配置文件和其他资源。

硬件抽象层

ROS提供了硬件抽象层,使得机器人应用可以在不同的硬件平台上运行,而不需要修改大量代码。这种方式提高了代码的可移植性。

工具和库

ROS提供了大量的工具和库,帮助开发者进行机器人开发。这些工具包括:

  • rviz:用于可视化机器人状态和传感器数据
  • gazebo:一个强大的机器人仿真平台,支持物理模拟
  • rqt:用于GUI开发的工具,提供了可视化的调试界面
  • rosbag:用于记录和回放机器人的传感器数据和消息

支持多种语言

ROS主要使用C++和Python编写,但也支持其他语言的接口(如Java、Lisp等),使得开发者可以使用自己熟悉的语言进行开发。

广泛的社区和生态系统

由于ROS是开源的,它拥有庞大的开发者社区,很多开发者分享自己的代码、工具和库。这些资源可以加速机器人开发。

ROS的生态系统包括许多常见的机器人模型、算法、仿真环境、传感器驱动和控制算法等。

多机器人系统

ROS支持多机器人系统,可以通过简单的配置实现多个机器人之间的协作和信息共享。

多个版本

目前,ROS有多个版本,主要有两个大版本:

  • ROS1:最初的ROS版本,广泛用于机器人开发,并且拥有丰富的社区支持。
  • ROS2:是ROS1的继任者,改进了性能、安全性、实时性和跨平台支持(如支持Windows和实时操作系统)。ROS2逐渐成为新项目的首选。

重要组成

  • URDF(Unified Robot Description Format)

URDF是ROS中用来描述机器人模型的标准文件格式。它定义了机器人各个组件(如链接、关节、传感器等)的物理属性和运动学结构。

通过URDF,开发者可以在仿真中创建机器人模型,或者将其用于控制和运动规划。

  • Xacro(XML Macros)

Xacro是一种扩展的XML格式,用来生成URDF文件。它通过提供参数化和宏功能,简化了复杂机器人的建模过程。

  • RViz

RViz是一个3D可视化工具,用于显示机器人在实际运行中的状态、传感器数据、地图、轨迹等。它可以实时更新,帮助开发者调试和监控机器人行为。

  • Gazebo

Gazebo是一个开源的仿真平台,它与ROS紧密集成,用于模拟机器人在各种环境中的行为。它支持物理引擎、传感器模拟和多机器人系统仿真。

  • MoveIt!

MoveIt!是一个广泛使用的机器人运动规划库,支持路径规划、避障、动力学求解等功能。它通过ROS与机器人控制系统进行集成。

什么是URDF

URDF是统一机器人描述格式(Unified Robot Description Format),用于描述机器人的物理结构、动力学属性和传感器等信息。它是机器人操作系统(ROS)中广泛使用的一种格式,通常用来定义机器人的模型。

作用

URDF描述机器人如下内容:

  1. 链接(Links)

表示机器人的刚体部分,如车轮、机械臂关节的连杆。

  1. 关节(Joints)

连接两个链接,定义它们之间的运动关系,如旋转关节(revolute)、滑动关节(prismatic)等。

  1. 惯性(Inertia)

定义每个部件的质量和惯性属性,用于动力学仿真。

  1. 视觉(Visual)

定义机器人部件的外观,通常通过网格文件(如STL或DAE)。

  1. 碰撞(Collision)

定义机器人部件的碰撞模型,用于物理引擎计算。

  1. 传感器和其他扩展

可以附加插件支持传感器、控制器等功能。

约定

URDF是基于XML的,主要有以下结构和规则:

基本结构

<robot name="robot_name">
  <!-- 链接 -->
  <link name="link1">
    <visual>
      <geometry>
        <box size="1 1 1" />
      </geometry>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>

  <!-- 关节 -->
  <joint name="joint1" type="revolute">
    <parent link="link1"/>
    <child link="link2"/>
    <origin xyz="0 0 0" rpy="0 0 0"/>
    <axis xyz="0 0 1"/>
  </joint>
</robot>

常用标签

  • <robot>: 顶层标签,定义机器人名称。
  • <link>: 描述单个部件(刚体)的几何、惯性、碰撞模型等。
  • <joint>: 描述部件之间的连接关系,包括运动约束。
  • <material>: 定义外观颜色或纹理。
  • <geometry>: 定义几何形状(立方体、圆柱体、球体、网格文件等)。

常用约束

  • 树形结构:URDF中的机器人模型必须是树形结构,不允许循环依赖。
  • 坐标系:每个链接、关节和插件都定义在一个三维坐标系下,通过origin标签设置位置和方向。
  • 单位:使用国际单位制(SI),如米、千克、秒等。

资源

学习资源

http://wiki.ros.org/urdf/Tutorials

ROS提供了详细的教程,涵盖了从零开始创建视觉模型、定义关节、添加物理属性以及使用Xacro优化文件的内容。这些教程是初学者入门的理想选择

https://github.com/ros/urdf_tutorial

ROS提供了开源的URDF教程代码,可以通过GitHub获取。这些示例包括RViz的可视化模型和Gazebo的仿真配置。

学习步骤

  • 基础XML语法:掌握XML文件的基本格式和书写规范。
  • 从简单模型开始:从一个简单的机器人(如两个链接和一个关节)开始练习。
  • 引入复杂元素:逐步添加惯性、碰撞模型、材质、传感器等元素。
  • 结合仿真和可视化工具:使用工具如RViz、Gazebo、MoveIt!来验证模型效果。

实践工具

  • URDF可视化工具

RViz:ROS内置可视化工具,检查URDF的结构和属性。

  • 仿真环境

Gazebo:结合URDF进行物理仿真。

  • Mesh编辑工具

Blender或SolidWorks制作和导出机器人模型的网格文件。

示例项目

  1. 下载开源机器人模型(如TurtleBotPR2Baxter),分析其URDF文件的结构。
  2. 使用URDF构建一个简单的四足机器人或机械臂模型。

URDF的扩展工具(Xacro)

什么是Xacro

Xacro是一种高效生成URDF文件的工具,通过Xacro可以更灵活地创建复杂、动态的机器人模型,而URDF则是最终格式,用于描述机器人结构并加载到ROS的仿真和控制环境中。

在很多URDF文件,我们会看到最终的文件后缀名是.xacro

image

文件后缀为.xacro表示这是一个Xacro文件,它是一种基于XML的宏扩展语言,全称为XML Macros

Xacro是ROS中用于生成URDF文件的工具。它允许通过参数化和复用减少重复代码,从而更高效地管理复杂机器人模型

为什么使用.xacro文件

  • 参数化

你可以定义变量(如机器人的尺寸、质量)并根据需求动态调整模型,而无需手动修改每个URDF文件。

  • 减少重复

如果一个机器人有多个相似的组件(如机械臂的多个关节),Xacro能通过宏模板生成这些组件,而不需要重复定义。

  • 模块化设计

使用<xacro:include>可以组合多个文件,方便将机器人描述分成不同部分,如底盘、机械臂等。

  • 动态生成

在加载URDF时,Xacro文件会被解析并转换为标准的URDF格式供工具(如Gazebo和RViz)使用。

如何将.xacro转换为URDF文件

使用ROS提供的xacro工具:

rosrun xacro xacro your_file.xacro > output_file.urdf

这将把.xacro文件转换为标准的.urdf文件,供仿真器或可视化工具直接使用。

示例

一个简单的Xacro文件可能如下:

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="example_robot">
  <xacro:property name="link_length" value="1.0"/>
  <link name="base_link">
    <visual>
      <geometry>
        <box size="${link_length} 0.2 0.1"/>
      </geometry>
    </visual>
  </link>
</robot>

这里的${link_length}是一个参数,可以动态修改其值生成不同的机器人模型。

和URDF之间的关系和区别

URDF是一种基于XML的静态文件格式,用于定义机器人的物理、视觉和运动属性。它是机器人模型的最终描述文件。

适用于

  • 静态、简单的结构:直接定义机器人的各部分(如链接和关节)。
  • 适合小型、简单的机器人模型。
  • 无法重复代码,无法进行参数化。
<robot name="simple_robot">
  <link name="base_link"/>
  <joint name="base_joint" type="fixed">
    <parent link="base_link"/>
    <child link="child_link"/>
  </joint>
</robot>

Xacro是一种基于XML的宏语言,专门用来生成URDF文件。它在语法上扩展了XML,允许使用变量、宏、条件和循环等高级功能。

适用于

  • 参数化:可以通过变量定义尺寸、质量等动态参数。
  • 模块化设计:通过<xacro:include>包含其他文件,支持将机器人模型分解为多个模块。
  • 简化重复:使用宏(xacro:macro)复用相同的代码片段。
  • 动态生成:Xacro文件在运行时被解析并转换为标准的URDF文件。
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="param_robot">
  <xacro:property name="link_length" value="1.0"/>
  <link name="base_link">
    <visual>
      <geometry>
        <box size="${link_length} 0.1 0.1"/>
      </geometry>
    </visual>
  </link>
</robot>

C#手动解析

1. 加载URDF文件

using System.Xml;

XmlDocument urdfDoc = new XmlDocument();
urdfDoc.Load("path_to_urdf_file.urdf"); // 替换为你的 URDF 文件路径

2. 解析URDF文件中的节点

URDF文件由<robot>根节点和多个<link><joint>子节点组成。可以通过XPath或递归方式获取这些节点。

  • 解析机器人名称
XmlNode robotNode = urdfDoc.SelectSingleNode("/robot");
string robotName = robotNode.Attributes["name"].Value;
Console.WriteLine("Robot Name: " + robotName);
  • 遍历所有链接节点
XmlNodeList linkNodes = urdfDoc.SelectNodes("/robot/link");
foreach (XmlNode link in linkNodes)
{
    string linkName = link.Attributes["name"].Value;
    Console.WriteLine("Link: " + linkName);
}
  • 遍历关节节点
XmlNodeList jointNodes = urdfDoc.SelectNodes("/robot/joint");
foreach (XmlNode joint in jointNodes)
{
    string jointName = joint.Attributes["name"].Value;
    string jointType = joint.Attributes["type"].Value;
    Console.WriteLine($"Joint: {jointName}, Type: {jointType}");
}

3. 处理几何和其他信息

URDF中的几何数据(如<visual><collision>)可能包含嵌套信息,例如网格文件路径、大小等。可以递归解析这些嵌套节点。

foreach (XmlNode link in linkNodes)
{
    XmlNode visualNode = link.SelectSingleNode("visual");
    if (visualNode != null)
    {
        XmlNode geometryNode = visualNode.SelectSingleNode("geometry");
        XmlNode meshNode = geometryNode?.SelectSingleNode("mesh");
        if (meshNode != null)
        {
            string meshFile = meshNode.Attributes["filename"].Value;
            Console.WriteLine($"Mesh file for link {link.Attributes["name"].Value}: {meshFile}");
        }
    }
}

4. 封装成类或数据结构

将URDF数据解析为C#类(如Robot,Link,Joint)以便操作:

class Robot
{
    public string Name { get; set; }
    public List<Link> Links { get; set; }
    public List<Joint> Joints { get; set; }
}

class Link
{
    public string Name { get; set; }
    public string MeshFile { get; set; }
}

class Joint
{
    public string Name { get; set; }
    public string Type { get; set; }
    public string ParentLink { get; set; }
    public string ChildLink { get; set; }
}

解析后填充这些类,便于进一步使用

5. 扩展支持动态仿真

如果你计划将解析后的URDF数据与物理引擎集成(例如Unity或Gazebo),可以将数据转换为这些框架支持的格式或接口。例如:

  • 使用Unity的GameObject动态加载URDF几何模型。
  • 与物理引擎(如Bullet或PhysX)对接。

第三方库支持

urdfdom(C++库)

https://github.com/ros/urdfdom

如果通过C++/CLI调用更底层的URDF库(如urdfdom),可以解析复杂URDF文件。

RosSharp(Unity-ROS工具包)

https://github.com/siemens/ros-sharp

一个C#项目,用于解析和运行ROS与Unity的桥接,支持URDF。

通过ROSSharp与ROS交互

ROSSharp是一个由社区开发的库,旨在为C#提供对ROS系统的支持。ROSSharp提供了ROS通信协议的C#实现,允许你通过ROS与C#代码进行交互。你可以用它来连接ROS网络、发布和订阅消息,以及发送服务请求。

安装ROSSharp

  1. ROSSharp官方GitHub仓库:

https://github.com/siemens/ros-sharp

你可以克隆这个仓库,或者在Visual Studio中创建一个新的C#项目并将ROSSharp添加为依赖项。

  1. 使用NuGet安装:

打开VisualStudio,进入“工具”->“NuGet包管理器”->“管理解决方案的NuGet包”。

搜索ROSSharp,然后将其添加到你的项目中。

示例代码

using System;
using ROSSharp.RosBridgeClient;

public class RosSubscriber
{
    private RosSocket rosSocket;

    public void Start()
    {
        rosSocket = new RosSocket("ws://localhost:9090"); // ROS Master 的 WebSocket 地址
        string topicName = "/chatter";
        rosSocket.Subscribe<std_msgs.String>(topicName, MessageReceived);
    }

    private void MessageReceived(std_msgs.String message)
    {
        Console.WriteLine("Received message: " + message.data);
    }
}

连接ROS Master:通过RosSocket连接到ROSMaster(通常运行在ws://localhost:9090)。

订阅话题:你可以订阅ROS中的任何话题,如/chatter,并定义如何处理接收到的消息。

ROSBridge和WebSocket

为了让C#与ROS通信,ROSBridge是一个非常有用的工具。ROSBridge是一个ROS包,它提供了一个WebSocket接口,可以让外部应用(如C#)与ROS节点进行通信。ROSBridge使用WebSocket协议,在网络上以JSON格式发送ROS消息。

安装ROSBridge

在你的ROS环境中,安装并启动ROSBridge:

sudo apt-get install ros-noetic-rosbridge-suite
roslaunch rosbridge_server rosbridge_websocket.launch

这会在ws://localhost:9090上启动一个WebSocket服务器,允许其他程序与ROS进行通信。

C#客户端与ROSBridge交互

在C#中,你可以使用WebSocketSharp库与ROSBridge进行WebSocket通信。通过WebSocket连接后,C#应用就可以发送和接收ROS消息。

WebSocketSharp安装:

你可以通过NuGet包管理器安装WebSocketSharp:

Install-Package WebSocketSharp

示例代码:

using WebSocketSharp;
using Newtonsoft.Json;
using System;

public class RosBridgeClient
{
    private WebSocket ws;

    public void Start()
    {
        ws = new WebSocket("ws://localhost:9090");
        ws.OnMessage += (sender, e) => { MessageReceived(e.Data); };
        ws.Connect();

        // 订阅话题
        var subscribeMessage = new
        {
            op = "subscribe",
            topic = "/chatter"
        };
        ws.Send(JsonConvert.SerializeObject(subscribeMessage));
    }

    private void MessageReceived(string message)
    {
        Console.WriteLine("Received: " + message);
    }
}

使用ROS2和C#

如果你在使用ROS2,虽然ROS2本身并不直接支持C#,但你可以通过一些第三方库(例如ros2-dotnet)实现与ROS2的交互。

ros2-dotnet是一个实验性项目,旨在提供ROS2和C#之间的通信。你可以通过以下链接找到它:

GitHub仓库:https://github.com/ros2-dotnet/ros2_dotnet

如何使用:

  • 克隆ros2_dotnet仓库,按照文档进行编译和安装。
  • 使用C#通过ROS2的DDS通信模型与ROS2节点进行交互。

参考

posted @ 2024-12-01 16:58  TaylorShi  阅读(13)  评论(0编辑  收藏  举报