ROS2 CANopen 使用教程(三)

本文涉及的产品
文档翻译,文档翻译 1千页
文本翻译,文本翻译 100万字符
资源编排,不限时长
简介: ROS2 CANopen 使用教程

ROS2 CANopen 使用教程(二)+https://developer.aliyun.com/article/1585396

2.8 如何创建配置包

       为了在机器人上使用ros2_canopen协议栈,您需要创建一个配置包,其中包含总线配置和启动脚本。下文将详细介绍创建配置包的步骤。

2.8.1 创建配置包

       创建配置包时,首先要做出一些决定。您需要选择软件包名称,决定需要哪些总线配置(通常是每个 CAN 接口一个),以及拥有哪些从站。

  • package_name:软件包名称
  • bus_config_name:总线配置的名称(可以有多个)。

       您可以使用 ros2 pkg create 命令创建软件包。

ros2 pkg create --dependencies canopen lely_core_libraries --build-type ament_cmake {package_name}
cd {package_name}
rm -rf src
rm -rf include
mkdir -p launch
mkdir -p config

        现在你的软件包目录应该是这样的。

{package_name}
├── config
├── launch
├── CMakeLists.txt
└── package.xml

2.8.2 创建总线配置

  1. 总线配置决策决定需要多少总线配置。在 config 文件夹中为每个总线配置添加一个子文件夹。
mkdir -p {bus_config_name}
  1. 为总线配置添加设备信息
    为总线配置创建文件夹后,将总线配置中设备的 .eds 文件添加到相应文件夹中。
    现在,您的软件包目录应该是这样的。
{package_name}
├── config
│   ├── {bus_config_name_1}
│   |   ├── {device1}.eds
│   |   ├── {device...}.eds
│   |   └── {slave_n}.eds
│   └── {bus_config_name_2}
│       ├── {device1}.eds
│       ├── {device...}.eds
│       └── {slave_n}.eds
├── CMakeLists.txt
└── package.xml
  1. 创建总线配置规范
    为指定总线配置,ros2_canopen 使用名为 bus.yml 的 YAML 文件。请在相应的总线配置文件夹中创建该文件。
touch bus.yml
{package_name}
├── config
│   ├── {bus_config_name_1}
│   |   ├── bus.yml
│   |   ├── {device1}.eds
│   |   ├── {device...}.eds
│   |   └── {slave_n}.eds
│   └── {bus_config_name_2}
│       ├── bus.yml
│       ├── {device1}.eds
│       ├── {device...}.eds
│       └── {slave_n}.eds
├── CMakeLists.txt
└── package.xml
  1. 编辑总线配置规范
    您需要根据需要修改每个 bus.yml 文件。首先,您需要定义这些文件和生成文件在运行时的位置。如果使用 colcon 从源代码构建,通常需要定义如下内容。
options:
  dcf_path: install/{package_name}/share/{package_name}/config/{bus_config_name}
  1. 然后,你需要确定你的主站。
master:
  node_id: [node id]
  package: [ros2 package where to find the master driver (usually canopen_core)]
  driver: [component type of the driver (ros2_canopen::MasterDriver or ros2_canopen::LifecycleMasterDriver)]
  1. 如果使用 ros2_canopen 的生命周期版本,请确保指定了生命周期主控程序。并根据需要添加其他配置数据。有关可用配置选项的文档,请参阅配置包文档。
    定义好主进程的配置后,就可以添加从进程了。下文介绍了每个从属设备的必填数据。更多配置选项请参阅配置包文档。从站名称是分配给驱动程序的节点名称。
nodes:
  - [unique slave name]:
    node_id: [node id]
    package: [ros2 package where to find the driver]
    driver: [qualified name of the driver]
  1. 如果使用生命周期版本的 ros2_canopen,请确保使用生命周期从属程序。

2.8.3 创建启动配置

       在软件包目录下创建启动文件夹和启动文件。

mkdir launch
touch {...}.launch.py

添加以下代码

def generate_launch_description():
      """Generate launch description with multiple components."""
      path_file = os.path.dirname(__file__)
      ld = launch.LaunchDescription()
      device_container = IncludeLaunchDescription(
          PythonLaunchDescriptionSource(
              [
                  os.path.join(get_package_share_directory("canopen_core"), "launch"),
                  "/canopen.launch.py",
              ]
          ),
          launch_arguments={
              "master_config": os.path.join(
                  get_package_share_directory("{package_name}"),
                  "config",
                  "{bus_config_name}",
                  "master.dcf",
              ),
              "master_bin": os.path.join(
                  get_package_share_directory("{package_name}"),
                  "config",
                  "{bus_config_name}",
                  "master.bin",
              ),
              "bus_config": os.path.join(
                  get_package_share_directory("{package_name}"),
                  "config",
                  "{bus_config_name}",
                  "bus.yml",
              ),
              "can_interface_name": "{can_interface_name i.e. can0}",
          }.items(),
      )
      ld.add_action(device_container)
      return ld

2.8.4 创建 CMAKE 配置

       最后,我们需要调整 CMakeLists.txt 文件,以正确接收所有内容。

cmake_minimum_required(VERSION 3.8)
project({package_name})
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(canopen_core REQUIRED)
find_package(canopen_interfaces REQUIRED)
find_package(canopen_base_driver REQUIRED)
find_package(canopen_proxy_driver REQUIRED)
find_package(lely_core_libraries REQUIRED)
cogen_dcf({bus_config_name})
install(DIRECTORY
  launch/
  DESTINATION share/${PROJECT_NAME}/launch/
)
install(DIRECTORY
  launch_tests/
  DESTINATION share/${PROJECT_NAME}/launch_tests/
)
if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()
ament_package()

2.9 如何使用 ros2_control 创建 cia301 系统?

       CiA 301 配置文件又称 CANopen 应用层,是 CANopen 协议的基础。它定义了 CANopen 系统中用于设备通信和网络管理的基本原则、通信服务和对象字典。

       CiA 301 配置文件定义了多项通信服务,允许设备交换数据和执行操作。这些服务包括用于在设备间传输对象数据的 SDO(服务数据对象)服务、用于实时数据交换的 PDO(过程数据对象)服务,以及用于网络初始化、设备状态控制和错误处理的 NMT(网络管理)服务。

       使用 ROS2 启动 CiA301 接口包括三个步骤:

  • 为总线和 ROS2_control 准备配置
  • 准备状态和命令接口
  • 最后是准备启动文件。

2.9.1 准备配置

       要使用 CiA301 配置文件的控制系统接口,我们应准备以下配置

  • bus_conf
  • master_dcf
  • master_bin
  • can_interface,(默认:vcan0)

       定义总线配置参数

master:
    node_id: 1
    driver: "ros2_canopen::MasterDriver"
    package: "canopen_master_driver"
    baudrate: 250
options:
    dcf_path: "@BUS_CONFIG_PATH@"
joint_1:
    node_id: 0x00
    dcf: "joint.eds"
    driver: "ros2_canopen::ProxyDriver"
    package: "canopen_proxy_driver"
    reset_communication: false
joint_2:
    node_id: 0x01
    dcf: "joint.eds"
    driver: "ros2_canopen::ProxyDriver"
    package: "canopen_proxy_driver"
    reset_communication: false

       定义 ros2_control 参数

controller_manager:
    ros__parameters:
        update_rate: 100  # Hz
        joint_state_broadcaster:
            type: joint_state_broadcaster/JointStateBroadcaster
        joint_1_controller:
            type: canopen_ros2_controllers/CanopenProxyController
        joint_2_controller:
            type: canopen_ros2_controllers/CanopenProxyController
    joint_1_controller:
        ros__parameters:
            joint: joint_1
   joint_2_controller:
        ros__parameters:
            joint: joint_2

        master_dcf 的示例见 https://github.com/ros-industrial/ros2_canopen/blob/master/canopen_tests/config/simple/simple.eds

2.9.2 使用 RPDO 访问当前状态

2.9.2.1 定义接头和 CANopen 数据结构

       第一步是定义一个结构,用于保存有关接头和相关 CANopen 数据的信息。该结构是 CANopen 网络的基础,可确保存储所有相关数据并在需要时进行访问。

2.9.2.2 PDO 索引和子索引

       每个过程数据对象(PDO)都有一个索引和一个子索引。索引是每个 PDO 的唯一标识符,将其与系统中的其他 PDO 区分开来。子索引用于访问每个 PDO 中的单个数据字段,因为一个 PDO 可以包含多个数据字段。

2.9.2.3 网络管理(NMT)

       网络管理(NMT)是 CANopen 协议套件中的一项基本服务。它提供基本的设备控制命令,如启动、停止和复位,并管理网络中设备的状态。

       对于 RPDO,使用以下方式定义数据:

"rpdo/index

"rpdo/subindex

"rpdo/type

"rpdo/data

       对于 NMT,我们可以通过以下方式读取状态

"nmt/state

2.9.3 使用 TPDO 发送命令

       为了向 CANopen 网络中的硬件设备发送命令,我们首先需要导出相应的硬件接口。这是一个关键步骤,可使我们有效地控制网络中的每个接头。

2.9.3.1 注册传输过程数据对象(TPDOs)

       与处理状态接口的方法类似,我们必须为每个关节注册传输过程数据对象(TPDOs)。这些 TPDO 与以下命令相关:

  • "tpdo/index
  • "tpdo/subindex
  • "tpdo/type
  • "tpdo/data
  • "tpdo/owns

2.9.3.2 网络管理 (NMT) 命令

       除此之外,我们还能注册与网络管理 (NMT) 相关的命令,以控制网络内设备的状态。这对设备的顺利运行和控制非常重要。与 NMT 相关的命令包括

  • "nmt/reset
  • "nmt/reset_fbk
  • "nmt/start
  • "nmt/start_fbk

       这些 NMT 命令不仅有助于管理设备状态,还能在执行命令后从设备向控制系统提供反馈(用 "fbk "表示)。这种反馈机制对于确保成功执行命令和管理网络的整体健康至关重要。

2.9.4 如何启动节点

       最后,我们为接口准备启动文件。示例见:https://github.com/ros-industrial/ros2_canopen/blob/master/canopen_ros2_control/launch/canopen_system.launch.py

       有关测试,请参阅以下部分。

2.10 如何使用 ros2_control 创建机器人系统

       本指南介绍如何利用 ros2_control 创建一个简单的机器人系统硬件接口。

  1. 创建一个新的配置包,名称为 canopen_robot_control_example。
ros2 pkg create --dependencies canopen lely_core_libraries --build-type ament_cmake {package_name}
cd {package_name}
rm -rf src
rm -rf include
mkdir -p launch
mkdir -p config
  1. 新建一个名为 robot_control 的总线配置文件夹。
mkdir -p config/robot_control
  1. 创建一个新的总线配置文件,文件名为 bus.yml。
touch config/robot_control/bus.yml
  1. 在 bus.yml 文件中添加以下内容
options:
  dcf_path: "@BUS_CONFIG_PATH@"
master:
  node_id: 1
  driver: "ros2_canopen::MasterDriver"
  package: "canopen_master_driver"
  sync_period: 10000
defaults:
  dcf: "cia402_slave.eds"
  driver: "ros2_canopen::Cia402Driver"
  package: "canopen_402_driver"
  period: 10
  position_mode: 1
  revision_number: 0
  sdo:
    - {index: 0x60C2, sub_index: 1, value: 50} # Set interpolation time for cyclic modes to 50 ms
    - {index: 0x60C2, sub_index: 2, value: -3} # Set base 10-3s
    - {index: 0x6081, sub_index: 0, value: 1000}
    - {index: 0x6083, sub_index: 0, value: 2000}
    - {index: 0x6060, sub_index: 0, value: 7}
  tpdo: # TPDO needed statusword, actual velocity, actual position, mode of operation
    1:
      enabled: true
      cob_id: "auto"
      transmission: 0x01
      mapping:
        - {index: 0x6041, sub_index: 0} # status word
        - {index: 0x6061, sub_index: 0} # mode of operation display
    2:
      enabled: true
      cob_id: "auto"
      transmission: 0x01
      mapping:
        - {index: 0x6064, sub_index: 0} # position actual value
        - {index: 0x606c, sub_index: 0} # velocity actual position
  rpdo: # RPDO needed controlword, target position, target velocity, mode of operation
    1:
      enabled: true
      cob_id: "auto"
      mapping:
      - {index: 0x6040, sub_index: 0} # controlword
      - {index: 0x6060, sub_index: 0} # mode of operation
    2:
      enabled: true
      cob_id: "auto"
      mapping:
      - {index: 0x607A, sub_index: 0} # target position
nodes:
  joint_1:
    node_id: 2
  joint_2:
    node_id: 3
  1. 将 canopen_tests/config/robot_control 软件包中的 cia402_slave.eds 文件复制到 config/robot_control 文件夹。
  2. 创建 ros2_controllers.yaml,并添加以下内容。
controller_manager:
  ros__parameters:
    update_rate: 100  # Hz
    joint_state_broadcaster:
      type: joint_state_broadcaster/JointStateBroadcaster
    forward_position_controller:
      type: forward_command_controller/ForwardCommandController
forward_position_controller:
  ros__parameters:
    joints:
      - joint1
      - joint2
    interface_name: position
  1. 在软件包的启动目录下创建一个名为 robot_control.launch.py 的启动文件,并添加以下内容。
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
def generate_launch_description():
    robot_description_content = Command(
        [
            PathJoinSubstitution([FindExecutable(name="xacro")]),
            " ",
            PathJoinSubstitution(
                [
                    FindPackageShare("canopen_tests"),
                    "urdf",
                    "robot_controller",
                    "robot_controller.urdf.xacro",
                ]
            ),
        ]
    )
    robot_description = {"robot_description": robot_description_content}
    robot_control_config = PathJoinSubstitution(
        [FindPackageShare("canopen_tests"), "config/robot_control", "ros2_controllers.yaml"]
    )
    control_node = Node(
        package="controller_manager",
        executable="ros2_control_node",
        parameters=[robot_description, robot_control_config],
        output="screen",
    )
    joint_state_broadcaster_spawner = Node(
        package="controller_manager",
        executable="spawner",
        arguments=["joint_state_broadcaster", "--controller-manager", "/controller_manager"],
    )
    forward_position_controller_spawner = Node(
        package="controller_manager",
        executable="spawner",
        arguments=["forward_position_controller", "--controller-manager", "/controller_manager"],
    )
    robot_state_publisher_node = Node(
        package="robot_state_publisher",
        executable="robot_state_publisher",
        output="both",
        parameters=[robot_description],
    )
    slave_config = PathJoinSubstitution(
        [FindPackageShare("canopen_tests"), "config/robot_control", "cia402_slave.eds"]
    )
    slave_launch = PathJoinSubstitution(
        [FindPackageShare("canopen_fake_slaves"), "launch", "cia402_slave.launch.py"]
    )
    slave_node_1 = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(slave_launch),
        launch_arguments={
            "node_id": "2",
            "node_name": "slave_node_1",
            "slave_config": slave_config,
        }.items(),
    )
    slave_node_2 = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(slave_launch),
        launch_arguments={
            "node_id": "3",
            "node_name": "slave_node_2",
            "slave_config": slave_config,
        }.items(),
    )
    nodes_to_start = [
        control_node,
        joint_state_broadcaster_spawner,
        forward_position_controller_spawner,
        robot_state_publisher_node,
        slave_node_1,
        slave_node_2
    ]
    return LaunchDescription(nodes_to_start)
  1. 创建 urdf 文件夹 将 canopen_tests/urdf/robot_controller 软件包中的所有文件添加到软件包的 urdf 文件夹中。
  2. 编辑软件包的 CMakeLists.txt 文件,在 find_package 部分后添加以下几行。
cogen_dcf(robot_control)
install(DIRECTORY
launch urdf
DESTINATION share/${PROJECT_NAME})
  1. 编译软件包并获取 setup.bash 文件的源代码。
  2. 启动启动文件
  3. 现在,您可以使用 forward_command_controller 控制器来控制机器人。您还可以在 rviz 中添加一个 tf 或机器人模型,并将固定框架设置为 base_link,从而实现机器人的可视化。您可以使用以下命令移动机器人。
ros2 topic pub /forward_position_controller/commands std_msgs/msg/Float64MultiArray "{data: [10.0,10.0]}"
ros2 service call /cia402_device_1/sdo_write canopen_interfaces/srv/COWrite "{index: 0x1600, subindex: 0x01, data: 0x60400010, type: 32}"
目录
相关文章
|
2月前
|
存储 自然语言处理 机器人
ROS2教程06 ROS2行动
这篇文章是关于ROS2(Robot Operating System 2)行动(Action)通信机制的教程,包括行动的概念、特点、命令行工具的使用,以及如何编写行动的客户端和服务器代码,并介绍了如何测试行动通信。
76 4
ROS2教程06 ROS2行动
|
2月前
|
机器人 Shell Python
ROS2教程05 ROS2服务
这篇文章是关于ROS2(Robot Operating System 2)服务的教程,涵盖了服务的概念、特性、命令行工具的使用,以及如何编写服务的服务器和客户端代码,并提供了测试服务通信机制的示例。
46 4
ROS2教程05 ROS2服务
|
2月前
|
传感器 算法 数据可视化
ROS2教程04 ROS2话题
这篇文章是关于ROS2(Robot Operating System 2)的教程,主要介绍了ROS2中话题的概念、特性、使用方式,以及如何编写发布者和订阅者的代码。
49 3
ROS2教程04 ROS2话题
|
2月前
|
存储 Ubuntu 安全
ROS2教程02 ROS2的安装、配置和测试
本文是关于ROS2(机器人操作系统2)的安装、配置和测试的教程。内容包括使用一键安装脚本快速安装ROS2 Humble版,手动安装步骤,设置语言环境、添加软件源、更新软件包、安装ROS2桌面版和开发工具,配置ROS2环境,创建工作空间,配置ROS2领域以避免网络冲突,以及如何删除ROS2。此外,还包括了测试ROS2是否安装成功的两个案例:基本的Topic通信测试和使用Turtlesim演示程序。适用于Ubuntu 22.04操作系统。
86 1
ROS2教程02 ROS2的安装、配置和测试
|
2月前
|
传感器 存储 Ubuntu
Azure Kinect DK + ROS1 Noetic使用教程
本文是Azure Kinect DK在Ubuntu20.04下配合ROS1 Noetic使用的教程,内容包括一键安装脚本、硬件介绍、安装SDK相关软件包、设置Udev规则、SDK基本测试、DK ROS基本测试,以及存在的一些重要缺陷和相关参考文献。教程详细指导了如何配置和使用Azure Kinect DK,提供了安装步骤和解决常见问题的方法。
45 1
Azure Kinect DK + ROS1 Noetic使用教程
|
2月前
|
传感器 自然语言处理 机器人
ROS2教程03 ROS2节点
本文是关于ROS2(机器人操作系统2)节点的教程,涵盖了节点的概念、特性、使用方法,以及如何编写、测试和使用ROS2节点相关的命令行工具。文章介绍了节点的独立性、任务执行、跨硬件分布和多语言编写能力。详细解释了如何启动节点、查看节点信息、编写节点代码(包括面向过程和面向对象的方法),以及如何为功能包添加依赖和入口点。此外,还探讨了重映射节点名称和使用节点命令行工具的方法,如 `ros2 node info` 和 `ros2 node list`。适合已安装ROS2 Humble和Ubuntu 22.04操作系统,并具有Shell基础知识的读者学习。
31 1
|
2月前
|
算法 数据可视化 机器人
ROS2教程01 ROS2介绍
本文是ROS2(机器人操作系统的下一代)的介绍教程,内容包括ROS2的诞生背景、核心功能、特点、框架以及与ROS1的比较。文章涵盖了ROS2的通信系统、框架和工具、生态系统、全球性社区支持、完全开源、跨平台特性、多机协同能力、实时系统支持和更强的稳定性。此外,还提供了ROS2架构的详细介绍资源链接,适合对ROS2感兴趣的读者学习和了解。
70 1
|
2月前
|
机器人 Shell 开发者
ROS2教程08 ROS2的功能包、依赖管理、工作空间配置与编译
这篇文章是关于ROS2(Robot Operating System 2)中功能包、依赖管理、工作空间配置和编译的教程,涵盖了ROS2工作空间的概念、如何获取和安装功能包的依赖、构建工作空间的步骤,以及如何创建和管理ROS2功能包,包括使用命令行工具对功能包进行操作的方法。
123 0
ROS2教程08 ROS2的功能包、依赖管理、工作空间配置与编译
|
2月前
|
编解码 机器人 C++
ROS2教程07 ROS2自定义消息接口
这篇文章是关于如何在ROS2(Robot Operating System 2)中创建和使用自定义消息类型的教程,包括消息类型的定义、特点、命令行工具的使用,以及如何编写和测试自定义消息类型接口的步骤。
24 0
ROS2教程07 ROS2自定义消息接口
|
2月前
|
传感器 NoSQL 算法
ROS Moveit 配置全网最详细教程
本文是关于ROS Moveit配置的全网最详细教程,提供了一键安装脚本,以及如何使用Moveit进行机器人运动规划的详细步骤和说明。文中还深入解析了Moveit的配置包文件、Moveit的源码,以及如何使用不同的运动规划算法(如CHOMP、LERP、STOMP)进行路径规划。
69 0
ROS Moveit 配置全网最详细教程

推荐镜像

更多
下一篇
无影云桌面