
Комментарии 33
Раз уж весь процесс "привязывания" заключается в создании симлинков, почему нельзя сразу открывать в софте по /dev/*/by-path/* вместо /dev/cam_left и иже с ними (к тому же, как я понимаю, все равно не сильно стандартные) - и не городить лишний конфиг, скрипт и юнит systemd?
Причин тому несколько: читаемость ссылок в коде, удобство использования стандартных пакетов для лидаров в ROS2 (конечно, переопределить параметры запуска, можно, а зачем?)
Спрашивать у работающих с железом, зачем лишний костыль - это смело :)
Подключать новые USB-устройства после запуска мы, конечно же, не будем.
Лично для меня идентификация только по by-path не кажется удобной, так как при наличии большого количество устройств не очень-то поймёшь, куда какой воткнул.
Зато, для примера, ESP32-С3 замечательно идентифицируются по серийному номеру, что позволяет давать произвольные имена устройствам.
Bus 001 Device 015: ID 303a:1001 Espressif USB JTAG/serial debug unit
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 [unknown]
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x303a Espressif
idProduct 0x1001 USB JTAG/serial debug unit
bcdDevice 1.01
iManufacturer 1 Espressif
iProduct 2 USB JTAG/serial debug unit
iSerial 3 80:65:99:2D:19:64На всякий случай, приведу пример использования. Создаем файл /etc/udev/rules.d/91-esp32.rules с содержимым:
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", ATTRS{serial}=="80:65:99:2D:19:64", SYMLINK+="gate_control_dev_1"Перезагружаем правила udev
sudo udevadm control --reload-rulesПодключаем ESP32-C3 с серийным номером, указанным выше и видим симлинк /dev/gate_control_dev_1
В случае отсутствия серийного номера, как для CH340, действительно приходится ориентироваться на by-path. Но для этого тоже достаточно udev. Например:
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7522", DEVPATH=="*/usb1/1-3/1-3:1.0/*", SYMLINK+="ch340_on_USB3-2"
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7522", DEVPATH=="*/usb1/1-4/1-4.4/1-4.4.3/1-4.4.3:1.0/*", SYMLINK+="ch340_on_USB3HUB-6"
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7522", DEVPATH=="*/usb1/1-4/1-4.4/1-4.4.4/1-4.4.4:1.0/*", SYMLINK+="ch340_on_USB3HUB-7"Тут первая строка - для встроенного в мой ноут второго порта USB3.0. Вторая - для шестого порта внешнего семипортового USB3.0 хаба. Третья - для седьмого порта того же хаба.
Идентификация по серийному номеру (или, например, MAC-адресу) имеет один существенный недостаток - надо настраивать для каждого экземпляра устройства.
Т.е. если вы делаете девайс с тремя сетевыми платами, серийно делаете, хотя бы по 100 штук в месяц - вас задолбает привязка по МАС-адресу каждой платы в каждом девайсе.
А ещё при ремонте - плату заменил, меняй правила в udev. А меняет - местный персонал, который открутить-прикрутить может, а вот прописать правило в udev - нет.
Это как минимум чрезвычайно неудобно.
--------------------
Можно конечно скрипт написать, типа "вставьте кабель/нажмите/где лампочка зажглась скажите" - который бы позволял более-менее автоматизировать привязку по серийнику. Но всё равно неудобно.
by-path удобно, когда у тебя устройства распаяны на плате и никто их местами менять не будет.
У меня так для разных арм девайсов наборы udev правил написаны и все ок.
Увидел сообщение и согласен с ним. Просто use-case'ом решил поделиться.
Я же изначально писал, что "для меня идентификация ТОЛЬКО по by-path не кажется удобной", что никак не обозначает, что я не пользуюсь идентификацией по by-path, когда это востребовано. То есть, я указал, что есть случаи, когда идентификация по серийному номеру удобней, чем по by-path. Поэтому ограничиваться только идентификацией по by-path я не хочу.
По by_path без привязки к серийнику появляется возможность быстро заменить модуль в полях или соревнованиях, не залезая в консоль, или проводя там меньше времени
И как из этого следует, что удобна идентификация ТОЛЬКО по by-path?
Тем, что by-path гарантирует, что на определённом порту датчик/актуатор будет правильно определён, даже если у него нет явных идентов по USB, и робототехническая логика подхватит устройство правильно.
Удобство для быстрого ремонта. Достаточно заменить засбоивший датчик/актуатор, без необходимости прописывать
При этом не защищает от ошибок, например, в случае, если подключили камеру туда, где должен быть лидар. Там уже дополнительный механизм нужен
Прочитайте, что сами написали. А теперь ответьте на заданный вопрос ещё раз внимательно прочитав на что отвечаете и не пропустив слово ТОЛЬКО
Или Вы действительно ярый противник свободы выбора и апологет "золотого молотка"?
Подождите, что имеете в виду под ТОЛЬКО?
Я вижу несколько способов идентификации устройств (прописание алиасов, как в случае с by-path, в расчет не беру)
VID/PID: очень широко, притом, если свои делать, либо дорого, либо есть риск на чужие VID/PID нарваться, если совместимость с другими девайсами отбрасываем. А использовать общие VID/PID приводит к случаю как с USB/UART: непонятно, что за устройство
По сериийному номеру: можем отличать разные экземпляры, но роботу надо прописать серийник устройства, чтобы он правильно с девайсом работал. Усложняет ремонт в полях. С другой стороны, если работать с однотипными девайсами, то так можно один от другого отличать в программе, и притом, ни с кем не перепутать
По строками Vendor/Model: годится для флешеров, например, или для программ настройки девайсов. Если использовать только их, то есть риск перепутать передние и задние лидары, например
Или что имеете в виду? Комбинации, которые дадут возможность однозначно идентифицировать девайсы?
Если чего-то не хватает, просто задайте уточняющий вопрос.
Если лишь бы перейти на личности, то я базар сворачиваю
Подождите, что имеете в виду под ТОЛЬКО?
Ровно то, что обозначает семантика этого слова в русском языке: "Выражает ограничение, выделение из множества, единственно, исключительно." (Толковый словарь Ожегова).
Я за свободу выбора и мне не удобно ограничивать себя только одним способом идентификации устройств по USB. Поэтому "для примера" я описал вариант идентификации по серийному номеру средствами udev. Так же, для примера, я ниже описал и вариант идентификации по by-path тоже средствами udev. Что Вам, по неведомым мне причинам, сильно не понравилось.
По сериийному номеру: можем отличать разные экземпляры, но роботу надо прописать серийник устройства, чтобы он правильно с девайсом работал.
Кто же мешает роботу определять по by-path, а инженеру при обслуживании этого робота - по серийному номеру? Особенно, если таких роботов много и у них должны быть разные прошивки каких-то МК.
Или что имеете в виду?
Я имею в виду, что "золотого молотка" не существует и ограничивать себя только одним способом решения задачи, по меньшей мере, неразумно. Всё очень просто. Я не подгоняю задачи под один "золотой молоток", а выбираю наиболее подходящий способ решения для каждой конкретной задачи.
Погодите, где именно я топлю против udev и топлю за мифический золотой молоток? Я только ЗА udev, но это только одно из средств.
Я топил против жёсткого прописания уникальных идентификаторов для каждого девайса прямо в конфиг-файлы udev, иначе это усложняет замену устройств.
Это в контексте робототехники, где важно иметь возможность быстро заменить девайсину, и так, чтобы другой инженер тоже смог это сделать.
Инженеру по ремонту проще понять из инструкции, что ЭТОТ датчик втыкать ТОЛЬКО в этот порт, а то работать не будет, а то еще и в конфиги лезть.
Для самоделок пофиг, Вы, возможно, и скорректируете и не видите ничего сложного. А что если сыну поручить? Коллеге?
А если имеете в виду, что ТОЛЬКО по by-path устройства идентифицировать не получится, потому что к порту может быть подключено что угодно, то да, упустил этот момент. Тогда один из вариантов: by-path + VID/PID. Потому как серийник нового устройства надо прописывать, а на это не каждый способен, да и не всегда есть такая возможность
Спасибо. Честно говоря мне эта мысль не приходила в голову. У меня сейчас 6 серийных устройств, все время в них путаюсь.
Практический вопрос: если исключить переходники с одинаковыми VID/PID и добавить подключение устройств не в те порты + переезд на другой вычислитель, то насколько такой подход удобнее предварительного программного опроса и последующего изменения путей в конфигурации перед запуском робота?
Зачем вы лидар в нижней части расположили?
С программным опросом сложность возникла как раз с лидером: он при получении "странных", с его точки зрения пакетов просто переставал работать до перезагрузки. А так, в процессе эксплуатации робота особо ничего переключать-то и не нужно (еще повторюсь: я занимаюсь образовательной робототехникой с школьниками).
По поводу лидара снизу: чтобы видеть низкие препятствия и защитить сам лидер, при этом сохранить полный обзор.
Я у себя в канале рассказываю про этот и другие проекты. Если интересно, добро пожаловать!
А почему бы не использовать аппаратные UART на RPi и ESP?
Я бы наверное решал задачу через libusb. Раз lsusb знает что куда подключено, значит решение у задачи есть.
Вот из моего makefile (нужно отделить FTDI232 от CH340, CP210x):
# Фильтрация из всех имеющихся /dev/ttyUSB* только того, который FTDI.
ttys := $(wildcard /dev/ttyUSB*)
BOOTPORT ?= $(foreach tty,$(ttys),$(shell udevadm info -q symlink -n $(tty) | sed -n 's%.*FTDI.*%$(tty)%p'))
А что такое /dev/serial/by-id/ и можно ли его использовать как серебряную пулю (вот тут рекомендуют)? И, если кто понимает как образуется ID_PORT - расскажите пожалуйста на примерах!
Как перестать гадать, что сегодня /dev/ttyUSB0: стабильная работа с USB в Linux Ubuntu