当前位置: 首页 > news >正文

ROS + UDEV管理开源小车rikirobot的USB设备

在弄清楚udev的规则后(可参考我的前一篇博文),我们来看一下rikirobot的设备管理。

rikirobot的源码大家可以去github.com上搜索下载,有很多热心的网友已经将其打包上传,包括我们下面要讨论的setup文件,例如,

https://github.com/ykevin/rikirobot_setup

项目使用usb接口(包括USB串口)进行通讯时,我们都希望有个固定的设备名供程序调用。由于usb为即插即用设备,udev又是动态随机命名,所以,很难保证每次设备的名称都不变;因此,我们需要编写一些名称映射规则文件,对usb设备进行设置。

规则文件以.rules作为扩展名,规则配置路径一般在:

/etc/udev/rules.d/*

由于这些文件有优先级,所以一般在名称前面加上一个数字,系统加载时会按照数字进行排序,数字小的排前面(优先级别相对较高)。


规则格式示例:
KERNEL=="ttyUSB*", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="xxxx", MODE:="0777",  SYMLINK+="device_name"
其中
ATTRS{idVendor}=="xxxx"
ATTRS{idProduct}=="xxxx"

从查询到的结果里进行配置。

下面我以我自己的通过ch340控制ROS小车进行通迅的实际配置为例进行说明。

通过查询命令

$ ls -l  /dev |grep USB
crw-rw---- 1 root dialout 188,   0 Jan 10 04:56 ttyUSB0
$ ls -l  /dev |grep serial
drwxr-xr-x 4 root root          80 Jan 10 04:56 serial

可以找到我们的串口设备;

$ lsusb
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 001 Device 003: ID 248a:8367 Maxxter USB2.0 Hub
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

再细看一下,

$lsusb  -v

可以查到所有的usb设备的详细信息,其中包括要找的ch340,内容如下

Bus 001 Device 004: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x1a86 QinHeng Electronics
  idProduct          0x7523 HL-340 USB-Serial adapter
  bcdDevice            2.64
  iManufacturer           0 
  iProduct                2 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0027
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower               98mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      1 
      bInterfaceProtocol      2 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               1

熟悉usb的朋友一下子就可以看出,这个usb的通信协议是bulk,其中endpoint为0x8?为IN,0x0?的为Out,例如,用户的通迅是EP2-0x82(IN)/0x02(out),还有一个中断传输端口EP1-0x81(IN)。具体想了解usb规范的可以到这里去看一下,

USB 2.0 Specification | USB-IF

设备的idVendor和idProduct分别为,

idVendor           0x1a86 QinHeng Electronics
idProduct          0x7523 HL-340 USB-Serial adapter

我们就可以建立一个规则,文件名称为
/etc/udev/rules.d/58-riki.rules

与ch340相对应的规则为内容为
KERNEL=="ttyUSB?", SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0777" SYMLINK+="rikibase"

规则文件配置完成后,执行命令
service udev reload
service udev restart
然后就可以在/dev下找到我们想看的rikibase了(如果不行的话,就重启吧),
ls /dev/rikibase

然后在ros相应的launch文件中,配置的参数就可以固定为 /dev/rikibase了。ros的launch文件 serial_port参数定义为/dev/rikibase可以实现对相应硬件的调用设置,而不必插拔usb后在查看到底是那个端口号反复修改launch文件。

全部开源riki底盘树莓派中系统使用的规则配置示例及说明:

58-riki.rules

KERNEL=="ttyACM?", SUBSYSTEM=="tty", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="0483", MODE="0777" SYMLINK+="rikibase"
KERNEL=="ttyACM?", SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE="0777" SYMLINK+="rikiarm_left"
KERNEL=="ttyACM?", SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0046", MODE="0777" SYMLINK+="rikiarm_right"
KERNEL=="ttyUSB?", SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{serial}=="0001", MODE="0777" SYMLINK+="rikilidar"
KERNEL=="ttyUSB?", SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0777" SYMLINK+="rikibase"
KERNEL=="ttyUSB?", SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="0777" SYMLINK+="rikibase"
KERNEL=="ttyUSB?", SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE="0777" SYMLINK+="rikilidar"

558-orbbec-usb.rules

# Make primesense device mount with writing permissions (default is read only for unknown devices)
SUBSYSTEM=="usb", ATTR{idProduct}=="0401", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="0402", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="0403", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="0404", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="0405", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="0406", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="0407", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="0408", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="0409", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"
SUBSYSTEM=="usb", ATTR{idProduct}=="040a", ATTR{idVendor}=="2bc5", MODE:="0666", OWNER:="ubuntu", GROUP:="video"

49-teensy.rules

ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1"
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666"

10-local-rpi.rules

SUBSYSTEM=="vchiq", GROUP="video", MODE="0660"

解释:

vchiq是个什么子系统?

VCHIQ is a command interface between the running Linux kernel and peripherals (among other things) in the VideoCore silicon. /dev/vchiq provides generic userspace access to those commands for use by (at minimum) the camera and audio subsystems as well. It's a decently dangerous interface to expose to random programs, hence the somewhat restrictive permissions by default.


40-scratch.rules

ATTRS{idVendor}=="0694", ATTRS{idProduct}=="0003", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev"


99-com.rules
SUBSYSTEM=="input", GROUP="input", MODE="0660"
SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660"
SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"
SUBSYSTEM=="bcm2835-gpiomem", GROUP="gpio", MODE="0660"

SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c '\
        chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio;\
        chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio;\
        chown -R root:gpio /sys$devpath && chmod -R 770 /sys$devpath\
'"

KERNEL=="ttyAMA[01]", PROGRAM="/bin/sh -c '\
        ALIASES=/proc/device-tree/aliases; \
        if cmp -s $ALIASES/uart0 $ALIASES/serial0; then \
                echo 0;\
        elif cmp -s $ALIASES/uart0 $ALIASES/serial1; then \
                echo 1; \
        else \
                exit 1; \
        fi\
'", SYMLINK+="serial%c"

本文结束

相关文章:

  • (ros//EnvironmentVariables)ros环境变量
  • ROS移植机器人小车:小车主机与从机电脑的通信
  • Linux查看版本和系统信息
  • ROS移植机器人小车: rikirobot试运行
  • Linux+Grub启动引导修复错误:Gnu Grub Version 2.04 Minimal BASH-like editing is supported...
  • Ubuntu下安装指定版本的cmake包
  • Ubuntu20.04编译安装Opencv4.5.5安装包报错:Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
  • Ubuntu20.04编译安装Opencv4.5.5
  • Linux如何查看内核版本并安装内核头文件linux-headers-generic
  • Linux中如何安装特定的gcc版本
  • Ubuntu 20.04 源码编译Paddle2.2.2
  • Ubuntu20.04源码编译PaddleOCR2.4
  • OpenCV导入时报错 ImportError: numpy.core.multiarray failed to import
  • OpenVINO2022.1+open_model_zoo例程的编译与使用
  • OpenCV cv::plugin::impl::DynamicLib::libraryLoad load ..opencv_core_parallel_tbb45 =>FAILED
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 230. Kth Smallest Element in a BST
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • Java读取Properties文件的六种方法
  • Js基础知识(一) - 变量
  • JS专题之继承
  • LeetCode算法系列_0891_子序列宽度之和
  • Node 版本管理
  • PaddlePaddle-GitHub的正确打开姿势
  • PHP变量
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Vue 重置组件到初始状态
  • Vue学习第二天
  • 从零搭建Koa2 Server
  • 基于Android乐音识别(2)
  • 前端技术周刊 2019-02-11 Serverless
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 微信支付JSAPI,实测!终极方案
  • 自动记录MySQL慢查询快照脚本
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • 回归生活:清理微信公众号
  • ​水经微图Web1.5.0版即将上线
  • #Linux(权限管理)
  • #Z0458. 树的中心2
  • #前后端分离# 头条发布系统
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (Forward) Music Player: From UI Proposal to Code
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (办公)springboot配置aop处理请求.
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (十) 初识 Docker file
  • (五)MySQL的备份及恢复
  • (转) Android中ViewStub组件使用
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)程序员疫苗:代码注入
  • (转)关于多人操作数据的处理策略
  • (转)可以带来幸福的一本书
  • (转)利用ant在Mac 下自动化打包签名Android程序