Начало работы с РОС
Начало работы с РОС

установка РОС

Для установки мы используем систему Ubuntu 20.04.

  • Добавить источник программного обеспечения ROS
Язык кода:javascript
копировать
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main">/etc/apt/sources.list.d/ros-latest.list'
  • Добавить ключ
Язык кода:javascript
копировать
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
  • УстановитьROS
Язык кода:javascript
копировать
sudo apt-get update
sudo apt install ros-noetic-desktop-full

Если это Ubuntu 18.04, вы можете использовать

Язык кода:javascript
копировать
sudo apt install ros-melodic-desktop-full

Установка займет много времени.

Добавьте переменные среды

Язык кода:javascript
копировать
sudo vim /etc/profile

Содержание следующее

Язык кода:javascript
копировать
source /opt/ros/noetic/setup.bash
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:~/ros_ws/src

Если это Ubuntu 18.04, то

Язык кода:javascript
копировать
source /opt/ros/melodic/setup.bash
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:~/ros_ws/src

осуществлять

Язык кода:javascript
копировать
source /etc/profile
sudo apt-get install python3-rosdep2
sudo vim /etc/hosts

Если это Ubuntu 18.04, то

Язык кода:javascript
копировать
source /etc/profile
sudo apt-get install python3-rosdep
sudo vim /etc/hosts

Добавить контент

Язык кода:javascript
копировать
199.232.28.133 raw.githubusercontent.com

осуществлять

Язык кода:javascript
копировать
sudo rm /etc/ros/rosdep/sources.list.d/20-default.list
sudo rosdep init
rosdep update

Если это Ubuntu 18.04, то

Язык кода:javascript
копировать
sudo rosdep init
rosdep update
  • Установитьrosinstall
Язык кода:javascript
копировать
sudo apt install python3-rosinstall python3-rosinstall-generator python3-wstool
sudo apt-get install ros-noetic-roslaunch

Если это Ubuntu 18.04, то

Язык кода:javascript
копировать
sudo apt install python3-catkin-pkg
sudo apt install python3-rosinstall python3-rosinstall-generator python3-wstool
sudo apt-get install ros-melodic-roslaunch

После завершения установки введите

Язык кода:javascript
копировать
roscore

выход

Язык кода:javascript
копировать
... logging to /home/guanjian/.ros/log/cb18d28e-35fe-11ee-b678-03d041231f43/roslaunch-guanjian-X99-38074.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://guanjian-X99:34311/
ros_comm version 1.16.0


SUMMARY
========

PARAMETERS
 * /rosdistro: noetic
 * /rosversion: 1.16.0

NODES

auto-starting new master
process[master]: started with pid [38083]
ROS_MASTER_URI=http://guanjian-X99:11311/

setting /run_id to cb18d28e-35fe-11ee-b678-03d041231f43
process[rosout-1]: started with pid [38093]
started core service [/rosout]

Указывает на успешную установку

  • тест
Язык кода:javascript
копировать
sudo apt install ros-noetic-rosbash
sudo apt install ros-noetic-catkin
sudo apt-get install ros-noetic-turtlesim

Если это Ubuntu 18.04, то

Язык кода:javascript
копировать
sudo apt install ros-melodic-rosbash
sudo apt install ros-melodic-catkin
sudo apt-get install ros-melodic-turtlesim

осуществлять

Язык кода:javascript
копировать
rosrun turtlesim turtlesim_node

Появится изображение маленькой черепахи.

осуществлять

Язык кода:javascript
копировать
rosrun turtlesim turtle_teleop_key

Таким образом, вы можете использовать клавиши со стрелками на клавиатуре, чтобы управлять маленькой черепахой.

  • Установитьrинструмент qt

Инструмент ros rqt — это серия интуитивно понятных инструментов визуализации, разработанных с использованием qt.

Язык кода:javascript
копировать
sudo apt-get install ros-noetic-rqt
sudo apt-get install ros-noetic-rqt-graph
sudo apt-get install ros-noetic-rqt-common-plugins

Если это Ubuntu 18.04, то

Язык кода:javascript
копировать
sudo apt-get install ros-melodic-rqt
sudo apt-get install ros-melodic-rqt-graph
sudo apt-get install ros-melodic-rqt-common-plugins
  • Установить Инструменты обработки и передачи изображений
Язык кода:javascript
копировать
sudo apt-get install ros-noetic-cv-bridge
sudo apt-get install ros-noetic-image-transport

Если это Ubuntu 18.04, то

Язык кода:javascript
копировать
sudo apt-get install ros-melodic-cv-bridge
sudo apt-get install ros-melodic-image-transport

Настройте каталог jetson nano opencv (только для 18.04)

Язык кода:javascript
копировать
cd /opt/ros/melodic/share/cv_bridge/cmake/
sudo vim cv_bridgeConfig.cmake

Измените две строки opencv 94 и 96 на opencv4.

Основные концепции ROS

механизм связи

ROS — это слабосвязанная распределенная программная среда. На рисунке выше много узлов. Каждый узел представляет собой процесс, выполняющий определенную функцию в системе робота. Например, некоторые узлы выполняют распознавание изображения, а некоторые — драйвер изображения. Между ними будет промежуток. .Идет передача серии изображений. Положения между узлами не фиксированы. Например, на рисунке выше изображены два компьютера: один A и один B. Некоторые узлы могут находиться в A, а некоторые узлы могут быть в B. Они могут быть соединены посредством серии передач. методы завершения общения. Язык программирования каждого узла не фиксирован. Вы можете использовать Python или C++.

На рисунке выше есть три узла: узел камеры, узел обработки изображения и узел отображения изображения.

  • Узел——осуществлять единицу
  • Узнать Процесс решения конкретных задач можно запустить самостоятельно, изучить документ;
  • Разные узлы могут использовать разные языки программирования и могут распространяться и запускаться на разных хостах;
  • Имена узлов должны быть уникальными в системе.
  • Менеджер узла (ROS Master) — Центр управления
  • Обеспечить именование и регистрацию Служить для узлов;
  • Отслеживание и запись темы/Служить коммуникациям,Вспомогательные узлы находят друг друга,установить соединение;
  • поставлятьпараметр Служитьустройство,Узел использует эту службу для хранения и получения параметров времени выполнения.

Существует два основных метода связи между узлами — темы и сервисы.

тема

  • Тема — асинхронный механизм связи.
  • Важная шина, используемая для передачи данных между узлами, это канал данных;
  • использоватьпубликовать/подписаться Модель,данные передаются от издателя подписчику,Подписчики или издатели одной и той же темы не могут быть уникальными. На приведенном выше рисунке есть узел публикации (Publisher,Например, узел камеры,Он опубликует данные изображения для обработки другими) и два узла подписки (подписчик,Узел, которому необходимо обработать данные изображения, выпущенные камерой.,Необходимо подписаться на узел камеры). данные Поток односторонний,От издателя к подписчику.
  • информация(Message)——темаданные
  • Он имеет определенные типы и структуры, включая стандартные типы и определяемые пользователем типы, предоставляемые ROS;
  • Определение .msgдокумента с использованием языка программирования никто,Соответствующий кодовый документ генерируется в процессе компиляции.

Служить

  • Служить(Service)——синхронныймеханизм связи
  • Использование модели клиент/Служить (C/S),Клиент отправляет запрос данных,Служитьустройство完成处理后возвращатьсяотвечатьданные,Это двусторонняя связь;
  • Определите структуры данных запроса и ответа, используя .srvдокумент языка программирования никто.,Соответствующий кодовый документ генерируется в процессе компиляции.

темаи Служить Разница

тема

Служить

синхронность

асинхронный

синхронный

модель связи

публиковать/подписаться

Служить исполнителю/заказчику

базовый протокол

ROSTCP/ROSUDP

ROSTCP/ROSUDP

механизм обратной связи

никто

иметь

буфер

иметь

никто

в реальном времени

слабый

мощный

Отношения узлов

многие ко многим

Один ко многим (один сервер)

Применимые сценарии

передача данных

логическая обработка

параметр

это в РОС Мастер поддерживает сервер параметр Служить, и ко всем узлам можно получить доступ через сеть.

  • параметр(Параметр)——Глобальный общий словарь.
  • Общий многопараметрический словарь, доступный по сети;
  • Этот Служить используется узлами для хранения и получения параметров времени выполнения;
  • Подходит для хранения статических, недвоичных параметров конфигурации.,данные не подходят для хранения динамической конфигурации.

файловая система

  • Функциональный пакет(Пакет)

Базовая единица программного обеспечения ROS, включая исходный код узла, файлы конфигурации, определения данных и т. д.

  • Манифест пакета

Запишите основную информацию о пакете функций, включая информацию об авторе, информацию о лицензии, параметры зависимостей, флаги компиляции и т. д.

  • Мета-пакеты

Организуйте несколько пакетов функций, которые служат одной и той же цели.

Инструмент командной строки ROS

Запустить ROS Master

Язык кода:javascript
копировать
roscore

Запустить узел

Язык кода:javascript
копировать
rosrun turtlesim turtlesim_node

Rosrun обычно означает два параметра,Первый параметрturtlesim — это имя пакета функций.,Второй параметрturtlesim_node — это узел,это узел эмулятора,Это маленькая черепаха, которую я видел раньше.

Запустить другой узел

Язык кода:javascript
копировать
rosrun turtlesim turtle_teleop_key

Этот узел представляет собой узел, который управляет движением маленькой черепахи с помощью клавиш вверх, вниз, влево и вправо на клавиатуре.

  • Инструменты анализа
Язык кода:javascript
копировать
rqt_graph

Это инструмент, отображающий расчетные схемы систем.,Ядром механизма связи ROS является вычислительный граф.,С помощью схемы можно быстро понять общую картину всей системы.

В этом интерфейсе перечислены узлы текущей системы (эллиптическая часть).,Вот 2 узла,Узел симулятора маленькой черепахи Turtlesim,Узел управления клавиатурой teleop_turtle. Между двумя узлами осуществляется передача данных.,Среди них есть тема/turtle1/cmd_vel,Специально используется для общения.

  • Команда просмотра узла графического интерфейса никто
Язык кода:javascript
копировать
rosnode

Вернусь в это время и значение параметра и параметра, стоящего за ним

Язык кода:javascript
копировать
rosnode is a command-line tool for printing information about ROS Nodes.

Commands:
	rosnode ping	test connectivity to node
	rosnode list	list active nodes
	rosnode info	print information about node
	rosnode machine	list nodes running on a particular machine or list machines
	rosnode kill	kill a running node
	rosnode cleanup	purge registration information of unreachable nodes

Type rosnode <command> -h for more detailed usage, e.g. 'rosnode ping -h'

В это время мы используем

Язык кода:javascript
копировать
rosnode list

Узел, который будет осуществлять деятельность

Язык кода:javascript
копировать
/rosout
/teleop_turtle
/turtlesim

Последние два узла v — это эмулятор маленькой черепахи и контроллер клавиатуры, который мы начали.,А /rosout — это тема ROS по умолчанию.,Он собирает информацию журнала всех узлов и передает ее в последующий интерфейс для отображения.,В общем, не стоит волноваться.

Просмотр конкретной информации об узле

Язык кода:javascript
копировать
rosnode info /turtlesim

Вернусь в это время

Язык кода:javascript
копировать
Node [/turtlesim]
Publications: 
 * /rosout [rosgraph_msgs/Log]
 * /turtle1/color_sensor [turtlesim/Color]
 * /turtle1/pose [turtlesim/Pose]

Subscriptions: 
 * /turtle1/cmd_vel [geometry_msgs/Twist]

Services: 
 * /clear
 * /kill
 * /reset
 * /spawn
 * /turtle1/set_pen
 * /turtle1/teleport_absolute
 * /turtle1/teleport_relative
 * /turtlesim/get_loggers
 * /turtlesim/set_logger_level


contacting node http://guanjian-X99:46261/ ...
Pid: 4769
Connections:
 * topic: /rosout
    * to: /rosout
    * direction: outbound (57873 - 127.0.0.1:56794) [27]
    * transport: TCPROS
 * topic: /turtle1/cmd_vel
    * to: /teleop_turtle (http://guanjian-X99:40209/)
    * direction: inbound (46338 - guanjian-X99:43423) [29]
    * transport: TCPROS

Где Публикации — это информация, опубликованная узлом, например /turtle1/pose. Turtlesim/Pose представляет положение детеныша черепахи. Подписки — это информация, на которую подписан узел. Здесь он подписывается на /turtle1/cmd_vel. Geometry_msgs/Twist представляет данные, отправленные с помощью команды клавиатуры, и управляет движением маленькой черепахи с помощью данных, на которые она подписана. Службы Служить выпускаются этим узлом, а некоторые конфигурации выполняются через Служить в. Внизу указаны идентификационные номера и нижний слой механизма. связи。

  • тема Инструменты
Язык кода:javascript
копировать
rostopic

Вернусь в это время и значение параметра и параметра, стоящего за ним

Язык кода:javascript
копировать
rostopic is a command-line tool for printing information about ROS Topics.

Commands:
	rostopic bw	display bandwidth used by topic
	rostopic delay	display delay of topic from timestamp in header
	rostopic echo	print messages to screen
	rostopic find	find topics by type
	rostopic hz	display publishing rate of topic    
	rostopic info	print information about active topic
	rostopic list	list active topics
	rostopic pub	publish data to topic
	rostopic type	print topic or field type

Type rostopic <command> -h for more detailed usage, e.g. 'rostopic echo -h'

Посмотреть текущий список имеющихся тем в системе

Язык кода:javascript
копировать
rostopic list

Вернуться в это время

Язык кода:javascript
копировать
/rosout
/rosout_agg
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

в/turtle1/cmd_vel — это тема, которая выдает инструкции управления для маленькой черепахи. Узел управления клавиатурой и узел управления маленькой черепахой взаимодействуют через эту тему.

Отдавайте команды для перемещения черепах

Язык кода:javascript
копировать
rostopic pub /turtle1/cmd_vel geometry_msgs/Twist '[1.0,0.0,0.0]' '[0.0,0.0,0.0]'

«1.0,0.0,0.0» здесь относится к линейной скорости, а «0.0,0.0,0.0» относится к угловой скорости. Geometry_msgs/Twist относится к структуре данных сообщения.

Эта команда заставит черепаху двигаться, но она остановится после перемещения на короткое время. Это связано с тем, что команда pub будет выполнена только один раз. Чтобы черепаха продолжала двигаться, ей необходимо задать цикл.

Язык кода:javascript
копировать
rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist '[1.0,0.0,0.0]' '[0.0,0.0,0.0]'

Здесь -r представляет частоту, как часто публиковать содержимое сообщения, -r 10 представляет 10 Гц, публикуя 10 раз в секунду.

Просмотр содержимого структуры данных сообщения

Язык кода:javascript
копировать
rosmsg show geometry_msgs/Twist

Здесь рассматривается структура данных geome_msgs/Twist, возвращаемая

Язык кода:javascript
копировать
geometry_msgs/Vector3 linear
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular
  float64 x
  float64 y
  float64 z
  • Служитьинструмент
Язык кода:javascript
копировать
rosservice

Вернусь в это время и значение параметра и параметра, стоящего за ним

Язык кода:javascript
копировать
Commands:
	rosservice args	print service arguments
	rosservice call	call the service with the provided args
	rosservice find	find services by service type
	rosservice info	print information about service
	rosservice list	list active services
	rosservice type	print service type
	rosservice uri	print service ROSRPC uri

Type rosservice <command> -h for more detailed usage, e.g. 'rosservice call -h'

Просмотреть все текущие

Язык кода:javascript
копировать
rosservice list

возвращаться

Язык кода:javascript
копировать
/clear
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/teleop_turtle/get_loggers
/teleop_turtle/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/get_loggers
/turtlesim/set_logger_level

Все, что можно Служить здесь, можно Служить в Turtle Simulator.

породить новую черепаху

Язык кода:javascript
копировать
rosservice call /spawn "x: 2.0
y: 2.0
theta: 0.0
name: 'turtle2'" 
  • запись темы
Язык кода:javascript
копировать
rosbag record -a -O cmd_record

Запись здесь означает запись,-a — сохранить все записи,-O означает сохранение данных в сжатый пакет.,cmd_record — сохраненное имя

возвращаться

Язык кода:javascript
копировать
[ INFO] [1691623907.802537745]: Recording to 'cmd_record.bag'.
[ INFO] [1691623907.803795811]: Subscribing to /rosout_agg
[ INFO] [1691623907.806439843]: Subscribing to /rosout
[ INFO] [1691623907.809232127]: Subscribing to /turtle1/pose
[ INFO] [1691623907.811861515]: Subscribing to /turtle1/color_sensor
[ INFO] [1691623907.815194941]: Subscribing to /turtle1/cmd_vel

Теперь мы можем управлять маленькой черепахой для выполнения упражнений. После завершения упражнения нажмите Ctrl-C в окне командной строки rosbag, чтобы результаты записи были сохранены. Сохраненный путь находится в /home/user, где находится пользователь. ваше собственное имя пользователя. Сохраненный файл называется cmd_record.bag.

  • темаповторение

темаповторение,Предположим, у нас есть человек-машина, которую необходимо отладить.,Но невозможно каждый раз запускать самолет на доводку,мы совершим полет,использоватьrosbag запись сохраняет всю информацию, вернуться в Воспроизводите данные в лаборатории и проводите эксперименты. Теперь давайте воспроизведем данные движения маленькой черепахи прямо сейчас.

Сначала закройте все предыдущие терминалы,Снова откройте оба терминала,Запустить ROS Узел эмулятора Мастера и маленькой черепахи.

Язык кода:javascript
копировать
rosbag play cmd_record.bag

Таким образом, мы видим, что путь, пройденный маленькой черепахой, такой же, как и записанный.

Создавайте рабочие пространства и пакеты функций

  • Рабочая область — это папка, в которой хранится информация, связанная с разработкой проекта.,Его можно разделить на
  • src: пространство кода (Источник Space),Разместите код для всех пакетов функций,Конфигурациядокумент
  • build:компилироватькосмос(Build Пробел), помещенный посередине документа, созданного в процессе компилирования, никто не требует внимания. на
  • dev: пространство разработки (Развитие Space),местокомпилироватьсгенерированная банкаосуществлятьдокумент,Библиотеки и скрипты
  • install:Установитькосмос(Install Пространство), разместите локацию Установить, контент должен быть продублирован с наличием места разработки.

набор команд

  • Создайте рабочую область (я в разделе «Документы»)
Язык кода:javascript
копировать
cd Documents/
mkdir -p catkin_ws/src
cd catkin_ws/src/
catkin_init_workspace

В настоящее время в рабочей области нет кода, но его все равно можно использовать.

  • компилировать рабочее пространство
Язык кода:javascript
копировать
cd ..
catkin_make install

В это время будут созданы еще три папки — build, devel, install.

  • Установить переменные среды
Язык кода:javascript
копировать
source devel/setup.bash
  • Создать пакет функций
Язык кода:javascript
копировать
cd src
catkin_create_pkg test_pkg std_msgs rospy roscpp

Здесь test_pkg — это имя пакета функций, а все следующие элементы — это зависимости ROS. std_msgs — это стандартная структура сообщения, определенная ROS, rospy — это вызов ROS на Python, а roscpp — это вызов ROS на C++.

Пакеты функций с одинаковыми именами не могут существовать в одной рабочей области; пакеты функций с одинаковыми именами могут существовать в разных рабочих областях.

Это будет в test_pkg

Язык кода:javascript
копировать
CMakeLists.txt  include  package.xml  src

Среди них include и src — это папки, include — для размещения заголовочных файлов C++, а src — для размещения кода .cpp.

  • компилировать Пакет функций

Вернитесь в папку catkin_ws.

Язык кода:javascript
копировать
cd ..
catkin_make
  • Установить переменные среды
Язык кода:javascript
копировать
source devel/setup.bash
  • Просмотр переменных среды рабочей области
Язык кода:javascript
копировать
echo $ROS_PACKAGE_PATH

Вернуться в это время

Язык кода:javascript
копировать
/home/user/Documents/catkin_ws/src:/opt/ros/noetic/share

Он указывает место, где ROS может найти наш пакет функций (пользователь — это ваше собственное имя пользователя).

  • Два важных документа в пакете функций

В test_pkg будет два важных элемента — CMakeLists.txt и package.xml. Давайте посмотрим на содержимое package.xml.

Язык кода:javascript
копировать
<?xml version="1.0"?>
<package format="2">
  <name>test_pkg</name>
  <version>0.0.0</version>
  <description>The test_pkg package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="guanjian@todo.todo">guanjian</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>


  <!-- Url tags are optional, but multiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/test_pkg</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, but could be -->
  <!-- Example: -->
  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->


  <!-- The *depend tags are used to specify dependencies -->
  <!-- Dependencies can be catkin packages or system dependencies -->
  <!-- Examples: -->
  <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
  <!--   <depend>roscpp</depend> -->
  <!--   Note that this is equivalent to the following: -->
  <!--   <build_depend>roscpp</build_depend> -->
  <!--   <exec_depend>roscpp</exec_depend> -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use build_export_depend for packages you need in order to build against this package: -->
  <!--   <build_export_depend>message_generation</build_export_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use exec_depend for packages you need at runtime: -->
  <!--   <exec_depend>message_runtime</exec_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <!-- Use doc_depend for packages you need only for building documentation: -->
  <!--   <doc_depend>doxygen</doc_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

Он будет содержать некоторую основную информацию: название пакета функций.,номер версии,описывать,Автор и адрес электронной почты автора,Также имеются зависимости ROS для следующих пакетов функций. Мы также можем добавить сюда зависимости вручную позже.

Затем содержимое CMakeLists.txt

Язык кода:javascript
копировать
cmake_minimum_required(VERSION 3.0.2)
project(test_pkg)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
)

## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)


## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()

################################################
## Declare ROS messages, services and actions ##
################################################

## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
##   your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
##   * add a build_depend tag for "message_generation"
##   * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
##   * If MSG_DEP_SET isn't empty the following dependency has been pulled in
##     but can be declared for certainty nonetheless:
##     * add a exec_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
##   * add "message_generation" and every package in MSG_DEP_SET to
##     find_package(catkin REQUIRED COMPONENTS ...)
##   * add "message_runtime" and every package in MSG_DEP_SET to
##     catkin_package(CATKIN_DEPENDS ...)
##   * uncomment the add_*_files sections below as needed
##     and list every .msg/.srv/.action file to be processed
##   * uncomment the generate_messages entry below
##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)

## Generate messages in the 'msg' folder
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

## Generate services in the 'srv' folder
# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )

## Generate actions in the 'action' folder
# add_action_files(
#   FILES
#   Action1.action
#   Action2.action
# )

## Generate added messages and services with any dependencies listed here
# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )

################################################
## Declare ROS dynamic reconfigure parameters ##
################################################

## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
##   * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
##   * add "dynamic_reconfigure" to
##     find_package(catkin REQUIRED COMPONENTS ...)
##   * uncomment the "generate_dynamic_reconfigure_options" section below
##     and list every .cfg file to be processed

## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
#   cfg/DynReconf1.cfg
#   cfg/DynReconf2.cfg
# )

###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES test_pkg
#  CATKIN_DEPENDS roscpp rospy std_msgs
#  DEPENDS system_lib
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

## Declare a C++ library
# add_library(${PROJECT_NAME}
#   src/${PROJECT_NAME}/test_pkg.cpp
# )

## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/test_pkg_node.cpp)

## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")

## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
#   ${catkin_LIBRARIES}
# )

#############
## Install ##
#############

# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html

## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# catkin_install_python(PROGRAMS
#   scripts/my_python_script
#   DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
#   RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
#   ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
#   LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
#   RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )

## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
#   DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
#   FILES_MATCHING PATTERN "*.h"
#   PATTERN ".svn" EXCLUDE
# )

## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
#   # myfile1
#   # myfile2
#   DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )

#############
## Testing ##
#############

## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_test_pkg.cpp)
# if(TARGET ${PROJECT_NAME}-test)
#   target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()

## Add folders to be run by python nosetests
# catkin_add_nosetests(test)

иметьзакрыватьCMakeLists.txtВы можете обратиться к введениюБазовая обработка C++вИспользование CMake

Реализация издательского программирования

реализация на С++

Войти в рабочую область

Язык кода:javascript
копировать
cd Documents/catkin_ws/src

Создайте новый пакет функций темы.

Язык кода:javascript
копировать
catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

Введите каталог src пакета функций.

Язык кода:javascript
копировать
cd learning_topic/src

Создайте нужные нам файлы C++.

Язык кода:javascript
копировать
vim velocity_publisher.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 *  Эта программа опубликует черепаху1/cmd_velтема с типом сообщения geome_msgs::Twist.
*/

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

using namespace ros;

int main(int argc, char **argv) {
    //Инициализация узла ROS
    init(argc, argv, "velocity_publisher");
    //Создаем дескриптор узла
    NodeHandle n;
    //Создаем издателя, публикуем тему с именем /turtle1/cmd_vel, тип сообщения — geometry_msgs::Twist, длина очереди — 10
    Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);
    //Устанавливаем частоту цикла
    Rate loop_rate(10);

    int count = 0;

    while(ok()) {
        //Инициализируем сообщение типа Geometry_msgs::Twist
	geometry_msgs::Twist vel_msg;
        //Устанавливаем линейный импульс маленькой черепахи
	vel_msg.linear.x = 0.5;
        //Устанавливаем момент импульса маленькой черепахи
	vel_msg.angular.z = 0.2;
        //опубликовать сообщение
	turtle_vel_pub.publish(vel_msg);
	ROS_INFO("Publish turtle velocity command[%0.2f m/s, %0.2f rad/s]", vel_msg.linear.x, vel_msg.angular.z);
        //Задержка в зависимости от частоты цикла
	loop_rate.sleep();
    }

    return 0;
}

О QueuePublisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);Возьмите картинку выше в качестве примера,Если издатель публикует очень быстро,Например, 10 000 раз в секунду.,Базовый Ethernet может быть не в состоянии отправлять,Здесь будет очередь,Сначала сохраните 10 000 сообщений в очереди.,Затем отправьте данные из очереди (кеша) на основе фактической возможности отправки. Одна из проблем заключается в том, что делать, если очередь заполнена.,Мы установили здесь 10,Если базовая способность слишком слабая,ROS по умолчанию отбрасывает данные с самой старой временной меткой.,Данные, которые первыми присоединятся к очереди, выдадут,Он всегда будет сохранять 10 данных — это самые последние данные. В это время произойдут некоторые пропадания кадров.

Вернитесь в папку Learning_topic и измените CMakelists.txt.

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})

Вернитесь в папку catkin_ws.,начинатькомпилировать

Язык кода:javascript
копировать
cd ../..
catkin_make

Установите переменные среды после завершения компиляции

Язык кода:javascript
копировать
source devel/setup.bash

Если мы не хотим устанавливать переменные среды каждый раз после компиляции, мы можем напрямую изменить /etc/profile.

Язык кода:javascript
копировать
sudo vim /etc/profile

Добавить контент

Язык кода:javascript
копировать
source /home/user/Documents/catkin_ws/devel/setup.bash

Измените пользователя на свое собственное имя пользователя

Язык кода:javascript
копировать
source /etc/profile

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic velocity_publisher

Таким образом, мы можем увидеть, как маленькая черепаха движется по кругу.

Реализация Python

Перейдите в папку пакета

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_topic

Создайте новую папку скриптов

Язык кода:javascript
копировать
mkdir scripts
cd scripts

Создайте нужные нам файлы Python

Язык кода:javascript
копировать
vim velocity_publisher.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта программа опубликует черепаху1/cmd_velтема с типом сообщения geome_msgs::Twist.

import rospy
from geometry_msgs.msg import Twist

def velocity_publisher():
    # Инициализация узла ROS
    rospy.init_node('velocity_publisher', anonymous=True)
    # Создайте издателя, опубликуйте тему с именем /turtle1/cmd_vel, тип сообщения — geometry_msgs::Twist, а длина очереди — 10.
    turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)
    # Установите частоту цикла
    rate = rospy.Rate(10)

    while not rospy.is_shutdown():
        # Инициализировать сообщение типа Geometry_msgs::Twist
        vel_msg = Twist()
        # Установите линейный импульс маленькой черепахи
        vel_msg.linear.x = 0.5
        # Установите угловой момент черепашки
        vel_msg.angular.z = 0.2
        # Опубликовать сообщение
        turtle_vel_pub.publish(vel_msg)
        rospy.loginfo("Publish turtle velocity command[%0.2f m/s, %0.2f rad/s]", vel_msg.linear.x, vel_msg.angular.z)
        # Задержка в зависимости от частоты цикла
        rate.sleep()

if __name__ == '__main__':

    try:
        velocity_publisher()
    except rospy.ROSInterruptException:
        pass

Установить разрешения

Язык кода:javascript
копировать
chmod 777 velocity_publisher.py

Здесь нам понадобится операционная среда Python,Подробную информацию см.乌班图УстановитьPytorch、Tensorflow Среда КудавУстановить Anaconda。

Установите два необходимых пакета

Язык кода:javascript
копировать
conda activate py39
pip install pyyaml
pip install rospkg

осуществлять Заказ(разные окна терминала)

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic velocity_publisher.py

Это будет иметь тот же эффект, что и использование C++ ранее.

Программная реализация Абонента

реализация на С++

Введите пакет функций Learning_topic

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_topic/src

Создайте нужные нам файлы C++.

Язык кода:javascript
копировать
vim pose_subscriber.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 *  Эта процедура подпишется на /turtle1/posetemа с типом сообщения черепахсим::Pose
*/

#include <ros/ros.h>
#include "turtlesim/Pose.h"

using namespace ros;

//После получения подписанного сообщения функция обратного вызова сообщения «Входить»
void poseCallback(const turtlesim::Pose::ConstPtr& msg) {
    //Распечатываем полученное сообщение
    ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f", msg->x, msg->y);
}

int main(int argc, char **argv) {
    //Инициализируем узел ROS
    init(argc, argv, "pose_subscriber");
    //Создаем дескриптор узла
    NodeHandle n;
    //Создаем подписчика, подписываемся на тему с именем /turtle1/pose и регистрируем обратный вызов FunctionposeCallback
    Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);
    //Цикл ожидания функции обратного вызова
    spin();

    return 0;
}

Вернитесь в папку Learning_topic и измените CMakelists.txt.

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
rosrun learning_topic pose_subscriber

В этот момент мы увидим,Используем клавиатуру, чтобы переместить черепаху,Координаты черепашки будут отображаться вpose_subscriber в режиме реального времени.

Язык кода:javascript
копировать
[ INFO] [1691889920.721039829]: Turtle pose: x:7.258318, y:6.718236
[ INFO] [1691889920.736960560]: Turtle pose: x:7.226329, y:6.717391
[ INFO] [1691889920.752859056]: Turtle pose: x:7.194340, y:6.716546
[ INFO] [1691889920.768800015]: Turtle pose: x:7.162352, y:6.715701
[ INFO] [1691889920.784756857]: Turtle pose: x:7.130363, y:6.714856
[ INFO] [1691889920.800640019]: Turtle pose: x:7.098374, y:6.714011
[ INFO] [1691889920.816949030]: Turtle pose: x:7.066385, y:6.713166
[ INFO] [1691889920.832867584]: Turtle pose: x:7.034396, y:6.712321
[ INFO] [1691889920.848822764]: Turtle pose: x:7.002407, y:6.711476
[ INFO] [1691889920.864732401]: Turtle pose: x:6.970418, y:6.710631
[ INFO] [1691889920.880662398]: Turtle pose: x:6.938430, y:6.709786
[ INFO] [1691889920.896609434]: Turtle pose: x:6.906441, y:6.708941
[ INFO] [1691889920.912486155]: Turtle pose: x:6.874452, y:6.708097
[ INFO] [1691889920.928392700]: Turtle pose: x:6.842463, y:6.707252
[ INFO] [1691889920.944258964]: Turtle pose: x:6.810474, y:6.706407
[ INFO] [1691889920.961082117]: Turtle pose: x:6.778485, y:6.705562
[ INFO] [1691889920.976929758]: Turtle pose: x:6.746497, y:6.704717
[ INFO] [1691889920.992809891]: Turtle pose: x:6.714508, y:6.703872
[ INFO] [1691889921.008716570]: Turtle pose: x:6.682519, y:6.703027
[ INFO] [1691889921.024568443]: Turtle pose: x:6.650530, y:6.702182
[ INFO] [1691889921.040418382]: Turtle pose: x:6.618541, y:6.701337
[ INFO] [1691889921.056245800]: Turtle pose: x:6.586552, y:6.700492
[ INFO] [1691889921.072179865]: Turtle pose: x:6.554564, y:6.699647
[ INFO] [1691889921.088081910]: Turtle pose: x:6.522575, y:6.698802
[ INFO] [1691889921.104950901]: Turtle pose: x:6.490586, y:6.697958
[ INFO] [1691889921.120758048]: Turtle pose: x:6.458597, y:6.697113
[ INFO] [1691889921.136643736]: Turtle pose: x:6.426608, y:6.696268
[ INFO] [1691889921.152551417]: Turtle pose: x:6.394619, y:6.695423
[ INFO] [1691889921.168359967]: Turtle pose: x:6.362630, y:6.694578
[ INFO] [1691889921.184151132]: Turtle pose: x:6.330642, y:6.693733
[ INFO] [1691889921.200989473]: Turtle pose: x:6.298653, y:6.692888
[ INFO] [1691889921.216881443]: Turtle pose: x:6.266664, y:6.692043
[ INFO] [1691889921.232730165]: Turtle pose: x:6.234675, y:6.691198
[ INFO] [1691889921.248579035]: Turtle pose: x:6.202686, y:6.690353
[ INFO] [1691889921.264415767]: Turtle pose: x:6.170697, y:6.689508
[ INFO] [1691889921.280488459]: Turtle pose: x:6.138709, y:6.688663
[ INFO] [1691889921.296428648]: Turtle pose: x:6.106719, y:6.687818
[ INFO] [1691889921.312561137]: Turtle pose: x:6.074731, y:6.686973
[ INFO] [1691889921.328623851]: Turtle pose: x:6.042742, y:6.686129
[ INFO] [1691889921.344572117]: Turtle pose: x:6.010753, y:6.685284
[ INFO] [1691889921.360503389]: Turtle pose: x:5.978765, y:6.684439
[ INFO] [1691889921.376510552]: Turtle pose: x:5.946775, y:6.683594
[ INFO] [1691889921.392376821]: Turtle pose: x:5.914787, y:6.682749
[ INFO] [1691889921.408252255]: Turtle pose: x:5.882798, y:6.681904
[ INFO] [1691889921.424182561]: Turtle pose: x:5.850809, y:6.681059
[ INFO] [1691889921.440997168]: Turtle pose: x:5.818820, y:6.680214
[ INFO] [1691889921.456974244]: Turtle pose: x:5.786831, y:6.679369
[ INFO] [1691889921.472901624]: Turtle pose: x:5.754842, y:6.678524
[ INFO] [1691889921.488752417]: Turtle pose: x:5.722854, y:6.677679
[ INFO] [1691889921.504541853]: Turtle pose: x:5.690865, y:6.676834
[ INFO] [1691889921.520481420]: Turtle pose: x:5.658876, y:6.675989
[ INFO] [1691889921.536294508]: Turtle pose: x:5.626887, y:6.675144
[ INFO] [1691889921.552146408]: Turtle pose: x:5.594898, y:6.674299
[ INFO] [1691889921.569002808]: Turtle pose: x:5.562910, y:6.673454
[ INFO] [1691889921.584837421]: Turtle pose: x:5.530921, y:6.672609
[ INFO] [1691889921.600731891]: Turtle pose: x:5.498932, y:6.671764
[ INFO] [1691889921.616585402]: Turtle pose: x:5.466943, y:6.670919
[ INFO] [1691889921.632283348]: Turtle pose: x:5.434954, y:6.670074
[ INFO] [1691889921.648109869]: Turtle pose: x:5.402965, y:6.669230
[ INFO] [1691889921.664930356]: Turtle pose: x:5.370976, y:6.668385
[ INFO] [1691889921.680713380]: Turtle pose: x:5.338987, y:6.667540
[ INFO] [1691889921.696535478]: Turtle pose: x:5.306999, y:6.666695
[ INFO] [1691889921.712416030]: Turtle pose: x:5.275010, y:6.665850
[ INFO] [1691889921.728232197]: Turtle pose: x:5.243021, y:6.665005
[ INFO] [1691889921.745038074]: Turtle pose: x:5.211032, y:6.664160
[ INFO] [1691889921.760931901]: Turtle pose: x:5.179043, y:6.663315
[ INFO] [1691889921.776834055]: Turtle pose: x:5.147054, y:6.662470
[ INFO] [1691889921.792767539]: Turtle pose: x:5.115066, y:6.661625
[ INFO] [1691889921.808459123]: Turtle pose: x:5.083077, y:6.660780
[ INFO] [1691889921.824286895]: Turtle pose: x:5.051088, y:6.659935
[ INFO] [1691889921.840047529]: Turtle pose: x:5.019099, y:6.659091
[ INFO] [1691889921.856934123]: Turtle pose: x:4.987110, y:6.658246
[ INFO] [1691889921.872885179]: Turtle pose: x:4.955122, y:6.657401
[ INFO] [1691889921.888850674]: Turtle pose: x:4.923132, y:6.656556
[ INFO] [1691889921.904637071]: Turtle pose: x:4.891144, y:6.655711
[ INFO] [1691889921.920525400]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889921.936351946]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889921.952293251]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889921.968227998]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889921.984134339]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.000248528]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.016049234]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.032805745]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.048755014]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.064654370]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.080874716]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.096607718]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.112706638]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.128915941]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.144914936]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.160984702]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.177018643]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.193078747]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.209113678]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.224127436]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.240169768]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.256324080]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.272499755]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.288732790]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.304789579]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.320181587]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.336206526]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.352138685]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.368140737]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.384148108]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.400700501]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.416652277]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.432593842]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.448592295]: Turtle pose: x:4.859155, y:6.654866
[ INFO] [1691889922.464510380]: Turtle pose: x:4.844141, y:6.626607
[ INFO] [1691889922.480414251]: Turtle pose: x:4.829126, y:6.598348
[ INFO] [1691889922.496464895]: Turtle pose: x:4.814111, y:6.570089
[ INFO] [1691889922.512310489]: Turtle pose: x:4.799097, y:6.541830
[ INFO] [1691889922.528349207]: Turtle pose: x:4.784082, y:6.513571
[ INFO] [1691889922.544370980]: Turtle pose: x:4.769068, y:6.485312
[ INFO] [1691889922.560248083]: Turtle pose: x:4.754053, y:6.457054
[ INFO] [1691889922.577109783]: Turtle pose: x:4.739038, y:6.428795
[ INFO] [1691889922.593036954]: Turtle pose: x:4.724024, y:6.400536
[ INFO] [1691889922.608748334]: Turtle pose: x:4.709010, y:6.372277
[ INFO] [1691889922.624707025]: Turtle pose: x:4.693995, y:6.344018
[ INFO] [1691889922.640377773]: Turtle pose: x:4.678980, y:6.315759
[ INFO] [1691889922.656179957]: Turtle pose: x:4.663966, y:6.287500
[ INFO] [1691889922.673095800]: Turtle pose: x:4.648952, y:6.259242
[ INFO] [1691889922.689029385]: Turtle pose: x:4.633937, y:6.230983
[ INFO] [1691889922.704937355]: Turtle pose: x:4.618922, y:6.202724
[ INFO] [1691889922.720833524]: Turtle pose: x:4.603908, y:6.174465
[ INFO] [1691889922.736665756]: Turtle pose: x:4.588893, y:6.146206
[ INFO] [1691889922.752540440]: Turtle pose: x:4.573879, y:6.117947
[ INFO] [1691889922.768437486]: Turtle pose: x:4.558865, y:6.089688
[ INFO] [1691889922.784340470]: Turtle pose: x:4.543850, y:6.061430
[ INFO] [1691889922.800856292]: Turtle pose: x:4.528835, y:6.033170
[ INFO] [1691889922.816584659]: Turtle pose: x:4.513821, y:6.004911
[ INFO] [1691889922.832443907]: Turtle pose: x:4.498806, y:5.976653
[ INFO] [1691889922.848296081]: Turtle pose: x:4.483792, y:5.948394
[ INFO] [1691889922.864194256]: Turtle pose: x:4.468777, y:5.920135
[ INFO] [1691889922.880319566]: Turtle pose: x:4.453763, y:5.891876
[ INFO] [1691889922.896377267]: Turtle pose: x:4.438748, y:5.863617
[ INFO] [1691889922.912208261]: Turtle pose: x:4.423734, y:5.835358
[ INFO] [1691889922.928163217]: Turtle pose: x:4.408719, y:5.807099
[ INFO] [1691889922.944079033]: Turtle pose: x:4.393704, y:5.778841
[ INFO] [1691889922.961042491]: Turtle pose: x:4.378690, y:5.750582
[ INFO] [1691889922.976970418]: Turtle pose: x:4.363676, y:5.722323
[ INFO] [1691889922.992911458]: Turtle pose: x:4.348661, y:5.694064
[ INFO] [1691889923.008767385]: Turtle pose: x:4.333647, y:5.665805
[ INFO] [1691889923.024388033]: Turtle pose: x:4.318632, y:5.637546
[ INFO] [1691889923.040400809]: Turtle pose: x:4.303617, y:5.609287
[ INFO] [1691889923.056351176]: Turtle pose: x:4.288603, y:5.581028
[ INFO] [1691889923.072266925]: Turtle pose: x:4.273589, y:5.552770
[ INFO] [1691889923.088966404]: Turtle pose: x:4.258574, y:5.524511
[ INFO] [1691889923.104873895]: Turtle pose: x:4.243559, y:5.496252
[ INFO] [1691889923.120768099]: Turtle pose: x:4.228545, y:5.467993
[ INFO] [1691889923.136684839]: Turtle pose: x:4.213531, y:5.439734
[ INFO] [1691889923.152652861]: Turtle pose: x:4.198516, y:5.411475
[ INFO] [1691889923.168529918]: Turtle pose: x:4.183501, y:5.383216
[ INFO] [1691889923.184425569]: Turtle pose: x:4.168487, y:5.354958
[ INFO] [1691889923.200321049]: Turtle pose: x:4.153472, y:5.326698
[ INFO] [1691889923.216245066]: Turtle pose: x:4.138458, y:5.298440
[ INFO] [1691889923.232117480]: Turtle pose: x:4.123443, y:5.270181
[ INFO] [1691889923.248347382]: Turtle pose: x:4.108429, y:5.241922
[ INFO] [1691889923.264763495]: Turtle pose: x:4.093414, y:5.213663
[ INFO] [1691889923.280874344]: Turtle pose: x:4.078400, y:5.185404
[ INFO] [1691889923.296933154]: Turtle pose: x:4.063385, y:5.157145
[ INFO] [1691889923.312867114]: Turtle pose: x:4.048371, y:5.128886
[ INFO] [1691889923.328798936]: Turtle pose: x:4.033356, y:5.100627
[ INFO] [1691889923.344686159]: Turtle pose: x:4.018342, y:5.072369
[ INFO] [1691889923.360580762]: Turtle pose: x:4.003327, y:5.044110
[ INFO] [1691889923.376477719]: Turtle pose: x:3.988312, y:5.015851
[ INFO] [1691889923.392365338]: Turtle pose: x:3.973298, y:4.987592
[ INFO] [1691889923.408245284]: Turtle pose: x:3.958283, y:4.959333
[ INFO] [1691889923.424220910]: Turtle pose: x:3.943269, y:4.931074
[ INFO] [1691889923.440230704]: Turtle pose: x:3.928254, y:4.902815
[ INFO] [1691889923.456247677]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.472085474]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.488275063]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.504411872]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.520561024]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.536727905]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.552894362]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.569033430]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.584207344]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.600343488]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.616486007]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.632656715]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.648807247]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.664947728]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.680075728]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.696253947]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.712429119]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.728567929]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.744711745]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.760895074]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.777058333]: Turtle pose: x:3.913240, y:4.874557
[ INFO] [1691889923.792188376]: Turtle pose: x:3.913240, y:4.874557

Реализация Python

Перейдите в папку сценариев, чтобы создать файл Python.

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_topic/scripts
vim pose_subscriber.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура подпишется на /turtle1/posetemа с типом сообщения черепахсим::Pose

import rospy
from turtlesim.msg import Pose
# После получения подписанного сообщения функция обратного вызова сообщения «Входить»
def poseCallback(msg):
    # Распечатать полученные сообщения
    rospy.loginfo("Turtle pose: x:%0.6f, y:%0.6f", msg.x, msg.y)

def pose_subscriber():
    # Инициализировать узел ROS
    rospy.init_node('pose_subscriber', anonymous=True)
    # Создайте подписчика, подпишитесь на тему с именем /turtle1/pose и зарегистрируйте функцию обратного вызоваposeCallback.
    rospy.Subscriber("/turtle1/pose", Pose, poseCallback)
    # Цикл ожидания функции обратного вызова
    rospy.spin()

if __name__ == '__main__':

    pose_subscriber()

Установить разрешения

Язык кода:javascript
копировать
chmod 777 pose_subscriber.py

осуществлять Заказ (разные окна терминала)

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
rosrun learning_topic pose_subscriber.py

Издатели и подписчики передачи изображений

Войти в рабочую область

Язык кода:javascript
копировать
cd Documents/catkin_ws/src

Создать новый пакет функций

Язык кода:javascript
копировать
catkin_create_pkg learning_transfer_img sensor_msgs cv_bridge roscpp std_msgs image_transport

Введите каталог src пакета функций.

Язык кода:javascript
копировать
cd learning_transfer_img/src

Создайте файл C++ издателя.

Язык кода:javascript
копировать
vim img_publisher.cpp

Содержание следующее

Язык кода:javascript
копировать
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>

using namespace ros;
using namespace cv;
using namespace std;
using namespace sensor_msgs;
     
int main(int argc, char** argv){
    //Инициализация узла ROS
    init(argc, argv, "image_publisher");
    //Создаем дескриптор узла
    NodeHandle n;
    //Создаем издатель передачи изображений и публикуем тему с именем /camera/image
    image_transport::ImageTransport it(n);
    image_transport::Publisher pub = it.advertise("/camera/image", 1);
    VideoCapture cap(0);
    if(!cap.isOpened()) return 1;
    Mat frame;
    //Инициализируем сообщение типа Sensor_msgs::ImagePtr
    ImagePtr msg;
    Rate loop_rate(1);
    while (ok()) {
        cap >> frame;
        if(!frame.empty()) {
            //Преобразуем Mat opencv в сообщение типа Sensor_msgs::ImagePtr
            msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();
            //опубликовать сообщение
            pub.publish(msg);
        }
        //Задержка в зависимости от частоты цикла
        loop_rate.sleep();
    }
    return 0;
}

Файл C++ для создания подписчика

Язык кода:javascript
копировать
vim img_subscriber.cpp

Содержание следующее

Язык кода:javascript
копировать
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>

using namespace ros;
using namespace cv;
using namespace std;
using namespace sensor_msgs;
 
void imageCallback(const ImageConstPtr& msg) {
    try {
        //Преобразуем сообщение типа Sensor_msgs::ImagePtr в OpenCV Mat и отображаем его
        imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
        waitKey(1);
    } catch (cv_bridge::Exception& e) {
        ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
    }
}
 
int main(int argc, char **argv) {
    //Инициализация узла ROS
    init(argc, argv, "img_subscriber");
    //Создаем дескриптор узла
    NodeHandle n;
    namedWindow("view");
    startWindowThread();
    //Создаем image_transport::Subscriber, подписываемся на тему /camera/image и регистрируем обратный вызов FunctionimageCallback
    image_transport::ImageTransport it(n);
    image_transport::Subscriber sub = it.subscribe("/camera/image", 1, imageCallback);
    //Цикл ожидания функции обратного вызова
    spin();
    destroyWindow("view");
    return 0;
}

Вернитесь в папку Learning_transfer_img и измените CMakelists.txt.

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
find_package(OpenCV)
include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(img_publisher src/img_publisher.cpp)
target_link_libraries(img_publisher ${catkin_LIBRARIES})
target_link_libraries(img_publisher ${OpenCV_LIBS})

add_executable(img_subscriber src/img_subscriber.cpp)
target_link_libraries(img_subscriber ${catkin_LIBRARIES})
target_link_libraries(img_subscriber ${OpenCV_LIBS})

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun learning_transfer_img img_subscriber
rosrun learning_transfer_img img_publisher

Определение и использование тематических сообщений

реализация на С++

Перейдите в папку пакета

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_topic

Создать новую папку сообщений

Язык кода:javascript
копировать
mkdir msg
cd msg

Создадим нужные нам файлы сообщений

Язык кода:javascript
копировать
vim Person.msg

Содержание следующее

Язык кода:javascript
копировать
string name
uint8 sex
uint8 age

uint8 unknown = 0
uint8 male    = 1
uint8 femal   = 2

Здесь мы создаем информацию о человеке. Это зависит от языка, и ROS будет преобразована в программу C++ или Python в соответствии с определением.

Установить правила компиляции

Вернитесь в папку Learning_topic, измените package.xml и добавьте зависимости пакета функций динамически создаваемой программы.

Язык кода:javascript
копировать
cd ..
vim package.xml

добавить виз Содержание следующее

Язык кода:javascript
копировать
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

в<build_depend>длякомпилироватьполагаться,<exec_depend>дляосуществлятьполагаться。

Изменить CMakeLists.txt

Язык кода:javascript
копировать
vim CMakeLists.txt

Содержание следующее

Язык кода:javascript
копировать
find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
  message_generation
)

add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES learning_topic
   CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
#  DEPENDS system_lib
)

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

В это время мы увидим дополнительные документы Person.h в разделе Documents/catkin_ws/devel/include/learning_topicОглавление.,Он автоматически генерируется компилятором ROS.,Содержание следующее

Язык кода:javascript
копировать
// Generated by gencpp from file learning_topic/Person.msg
// DO NOT EDIT!


#ifndef LEARNING_TOPIC_MESSAGE_PERSON_H
#define LEARNING_TOPIC_MESSAGE_PERSON_H


#include <string>
#include <vector>
#include <memory>

#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>


namespace learning_topic
{
template <class ContainerAllocator>
struct Person_
{
  typedef Person_<ContainerAllocator> Type;

  Person_()
    : name()
    , sex(0)
    , age(0)  {
    }
  Person_(const ContainerAllocator& _alloc)
    : name(_alloc)
    , sex(0)
    , age(0)  {
  (void)_alloc;
    }



   typedef std::basic_string<char, std::char_traits<char>, typename std::allocator_traits<ContainerAllocator>::template rebind_alloc<char>> _name_type;
  _name_type name;

   typedef uint8_t _sex_type;
  _sex_type sex;

   typedef uint8_t _age_type;
  _age_type age;



// reducing the odds to have name collisions with Windows.h 
#if defined(_WIN32) && defined(unknown)
  #undef unknown
#endif
#if defined(_WIN32) && defined(male)
  #undef male
#endif
#if defined(_WIN32) && defined(femal)
  #undef femal
#endif

  enum {
    unknown = 0u,
    male = 1u,
    femal = 2u,
  };


  typedef boost::shared_ptr< ::learning_topic::Person_<ContainerAllocator> > Ptr;
  typedef boost::shared_ptr< ::learning_topic::Person_<ContainerAllocator> const> ConstPtr;

}; // struct Person_

typedef ::learning_topic::Person_<std::allocator<void> > Person;

typedef boost::shared_ptr< ::learning_topic::Person > PersonPtr;
typedef boost::shared_ptr< ::learning_topic::Person const> PersonConstPtr;

// constants requiring out of line definition

   

   

   



template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::learning_topic::Person_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::learning_topic::Person_<ContainerAllocator> >::stream(s, "", v);
return s;
}


template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator==(const ::learning_topic::Person_<ContainerAllocator1> & lhs, const ::learning_topic::Person_<ContainerAllocator2> & rhs)
{
  return lhs.name == rhs.name &&
    lhs.sex == rhs.sex &&
    lhs.age == rhs.age;
}

template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator!=(const ::learning_topic::Person_<ContainerAllocator1> & lhs, const ::learning_topic::Person_<ContainerAllocator2> & rhs)
{
  return !(lhs == rhs);
}


} // namespace learning_topic

namespace ros
{
namespace message_traits
{





template <class ContainerAllocator>
struct IsMessage< ::learning_topic::Person_<ContainerAllocator> >
  : TrueType
  { };

template <class ContainerAllocator>
struct IsMessage< ::learning_topic::Person_<ContainerAllocator> const>
  : TrueType
  { };

template <class ContainerAllocator>
struct IsFixedSize< ::learning_topic::Person_<ContainerAllocator> >
  : FalseType
  { };

template <class ContainerAllocator>
struct IsFixedSize< ::learning_topic::Person_<ContainerAllocator> const>
  : FalseType
  { };

template <class ContainerAllocator>
struct HasHeader< ::learning_topic::Person_<ContainerAllocator> >
  : FalseType
  { };

template <class ContainerAllocator>
struct HasHeader< ::learning_topic::Person_<ContainerAllocator> const>
  : FalseType
  { };


template<class ContainerAllocator>
struct MD5Sum< ::learning_topic::Person_<ContainerAllocator> >
{
  static const char* value()
  {
    return "2df326301c118b26e23f3606868068cc";
  }

  static const char* value(const ::learning_topic::Person_<ContainerAllocator>&) { return value(); }
  static const uint64_t static_value1 = 0x2df326301c118b26ULL;
  static const uint64_t static_value2 = 0xe23f3606868068ccULL;
};

template<class ContainerAllocator>
struct DataType< ::learning_topic::Person_<ContainerAllocator> >
{
  static const char* value()
  {
    return "learning_topic/Person";
  }

  static const char* value(const ::learning_topic::Person_<ContainerAllocator>&) { return value(); }
};

template<class ContainerAllocator>
struct Definition< ::learning_topic::Person_<ContainerAllocator> >
{
  static const char* value()
  {
    return "string name\n"
"uint8 sex\n"
"uint8 age\n"
"\n"
"uint8 unknown = 0\n"
"uint8 male    = 1\n"
"uint8 femal   = 2\n"
;
  }

  static const char* value(const ::learning_topic::Person_<ContainerAllocator>&) { return value(); }
};

} // namespace message_traits
} // namespace ros

namespace ros
{
namespace serialization
{

  template<class ContainerAllocator> struct Serializer< ::learning_topic::Person_<ContainerAllocator> >
  {
    template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
    {
      stream.next(m.name);
      stream.next(m.sex);
      stream.next(m.age);
    }

    ROS_DECLARE_ALLINONE_SERIALIZER
  }; // struct Person_

} // namespace serialization
} // namespace ros

namespace ros
{
namespace message_operations
{

template<class ContainerAllocator>
struct Printer< ::learning_topic::Person_<ContainerAllocator> >
{
  template<typename Stream> static void stream(Stream& s, const std::string& indent, const ::learning_topic::Person_<ContainerAllocator>& v)
  {
    s << indent << "name: ";
    Printer<std::basic_string<char, std::char_traits<char>, typename std::allocator_traits<ContainerAllocator>::template rebind_alloc<char>>>::stream(s, indent + "  ", v.name);
    s << indent << "sex: ";
    Printer<uint8_t>::stream(s, indent + "  ", v.sex);
    s << indent << "age: ";
    Printer<uint8_t>::stream(s, indent + "  ", v.age);
  }
};

} // namespace message_operations
} // namespace ros

#endif // LEARNING_TOPIC_MESSAGE_PERSON_H

Это заголовочный файл C++.

Создание издателей и подписчиков

Введите папку с исходным кодом Learning_topic.

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_topic/src

Создать издателя

Язык кода:javascript
копировать
vim person_publisher.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура опубликует /person_infotema, пользовательский тип сообщения Learning_topic::Person.
 */

#include <ros/ros.h>
#include "learning_topic/Person.h"

using namespace ros;

int main(int argc, char **argv) {
    //Инициализация узла ROS
    init(argc, argv, "person_publisher");
    //Создаем дескриптор узла
    NodeHandle n;
    //Создаем издателя, публикуем тему с именем /person_info, тип сообщения — Learning_topic::Person, длина очереди — 10.
    Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);
    //Устанавливаем частоту цикла
    Rate loop_rate(1);

    int count = 0;
    while(ok()) {
        //Инициализируем Learning_topic::Сообщение о типе человека
	learning_topic::Person person_msg;
	person_msg.name = "Tom";
	person_msg.age = 18;
	person_msg.sex = learning_topic::Person::male;
        //опубликовать сообщение
	person_info_pub.publish(person_msg);

	ROS_INFO("Publish Person Info: name:%s age:%d sex:%d", person_msg.name.c_str(), person_msg.age, person_msg.sex);
        //Задержка в зависимости от частоты цикла
	loop_rate.sleep();
    }

    return 0;
}

Создать подписчика

Язык кода:javascript
копировать
vim person_subscriber.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура подпишется на /person_infotema, пользовательский тип сообщения Learning_topic::Person
 */

#include <ros/ros.h>
#include "learning_topic/Person.h"

using namespace ros;

//После получения сообщения о подписке функция обратного вызова сообщения «Входить»
void personInfoCallback(const learning_topic::Person::ConstPtr& msg) {
    //Распечатываем полученное сообщение
    ROS_INFO("Subcribe Person Info: name:%s age:%d sex:%d", msg->name.c_str(), msg->age, msg->sex);
}

int main(int argc, char **argv) {
    //Инициализируем узел ROS
    init(argc, argv, "person_subscriber");
    //Создаем дескриптор узла
    NodeHandle n;
    //Создаем подписчика, подписываемся на тему с именем /person_info и регистрируем обратный вызов FunctionpersonInfoCallback
    Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);
    //Цикл ожидания функции обратного вызова
    spin();

    return 0;
}

вернуться в learning_topic папка, изменить CMakelists.txt

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${catkin_LIBRARIES})
add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)

add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${catkin_LIBRARIES})
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun learning_topic person_subscriber
rosrun learning_topic person_publisher

Таким образом, на стороне издательства всегда будут публиковаться новости персонала.

Язык кода:javascript
копировать
[ INFO] [1692058319.598902884]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058320.599045308]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058321.599024124]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058322.599034397]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058323.599010303]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058324.599021551]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058325.599007207]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058326.598998586]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058327.598991095]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058328.599036958]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058329.599018178]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058330.599023816]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058331.599021355]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058332.599022894]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058333.599017425]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1692058334.599010853]: Publish Person Info: name:Tom age:18 sex:1

И абонент начнет получать сообщения от людей.

Язык кода:javascript
копировать
[ INFO] [1692058320.599351163]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058321.599261038]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058322.599291722]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058323.599267429]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058324.599267875]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058325.599275965]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058326.599178858]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058327.599225550]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058328.599308836]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058329.599291376]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058330.599301795]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058331.599281126]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058332.599277659]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058333.599294180]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1692058334.599276274]: Subcribe Person Info: name:Tom age:18 sex:1

В настоящее время, если мы отключим ROS Master, то есть roscore, связь между двумя узлами издателя и подписчика не пострадает. Просто мы не можем расширять новые узлы для связи с этими двумя узлами.

Реализация Python

Перейдите в папку сценариев пакета.

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_topic/scripts

Создать издателя

Язык кода:javascript
копировать
vim person_publisher.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура опубликует /person_infotema, пользовательский тип сообщения Learning_topic::Person.

import rospy
from learning_topic.msg import Person

def velocity_publisher():
    # Инициализация узла ROS
    rospy.init_node('person_publisher', anonymous=True)
    # Создайте издателя, опубликуйте тему с именем /person_info, тип сообщения — Learning_topic::Person, а длина очереди — 10.
    person_info_pub = rospy.Publisher('/person_info', Person, queue_size=10)
    # Установите частоту цикла
    rate = rospy.Rate(10)

    while not rospy.is_shutdown():
        # Инициализировать Learning_topic::Сообщение типа человека
        person_msg = Person()
        person_msg.name = "Tom"
        person_msg.age = 18
        person_msg.sex = Person.male
        # Опубликовать сообщение
        person_info_pub.publish(person_msg)
        rospy.loginfo("Publish person message[%s, %d, %d]", person_msg.name, person_msg.age, person_msg.sex)
        # Задержка в зависимости от частоты цикла
        rate.sleep()

if __name__ == '__main__':

    try:
        velocity_publisher()
    except rospy.ROSInterruptException:
        pass

Создать подписчика

Язык кода:javascript
копировать
vim person_subscriber.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура подпишется на /person_infotema, пользовательский тип сообщения Learning_topic::Person

import rospy
from learning_topic.msg import Person

# После получения сообщения о подписке функция обратного вызова сообщения «Входить»
def personInfoCallback(msg):
    rospy.loginfo("Subcribe Person info: name:%s age:%d sex:%d", msg.name, msg.age, msg.sex)
    
def person_subscriber():
    # Инициализировать узел ROS
    rospy.init_node('person_subscriber', anonymous=True)
    # Создайте подписчика, подпишитесь на тему с именем /person_info и зарегистрируйте обратный вызов FunctionpersonInfoCallback.
    rospy.Subscriber('/person_info', Person, personInfoCallback)
    # Цикл ожидания функции обратного вызова
    rospy.spin()
    
if __name__ == '__main__':
    
    person_subscriber()

Дайте им разрешение

Язык кода:javascript
копировать
chmod 777 person_publisher.py
chmod 777 person_subscriber.py

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun learning_topic person_subscriber.py
rosrun learning_topic person_publisher.py

Клиентская реализация Сервиса

реализация на С++

Войти в рабочую область

Язык кода:javascript
копировать
cd Documents/catkin_ws/src

Создать новый пакет функций «Служить»

Язык кода:javascript
копировать
catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim

Введите каталог src пакета функций.

Язык кода:javascript
копировать
cd learning_service/src

Создайте нужные нам файлы C++.

Язык кода:javascript
копировать
vim turtle_spawn.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура запросит /spawn Служить, Служить данные типа черепахисим::Spawn
 */

#include <ros/ros.h>
#include <turtlesim/Spawn.h>

using namespace ros;

int main(int argc, char** argv) {
    //Инициализируем узел ROS
    init(argc, argv, "turtle_spawn");
    //Создаем дескриптор узла
    NodeHandle node;
    //После обнаружения /spawn Служить создайте клиент Служить и подключитесь к сервису с именем /spawn
    service::waitForService("/spawn");
    ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");
    //Инициализируем черепаху::Spawn запрос данных
    turtlesim::Spawn srv;
    srv.request.x = 2.0;
    srv.request.y = 2.0;
    srv.request.name = "turtle2";
    //просить Служитьвызов    ROS_INFO("Call service to spwan turtle[x:%0.6f, y:%0.6f, name:%s]", srv.request.x, srv.request.y, srv.request.name.c_str());

    add_turtle.call(srv);
    //Показать результаты Служитьвызов
    ROS_INFO("Spwan turtle successfully [name:%s]", srv.response.name.c_str());

    return 0;
}

Эта функция в основном используется для создания второй черепахи в эмуляторе черепахи.

вернуться в learning_service папка, изменить CMakelists.txt。

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
add_executable(turtle_spawn src/turtle_spawn.cpp)
target_link_libraries(turtle_spawn ${catkin_LIBRARIES})

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_spawn

На этом этапе мы уже можем видеть вторую черепаху, появившуюся в окне эмулятора черепахи. и распечатать журнал

Язык кода:javascript
копировать
[ INFO] [1692399646.686858318]: Call service to spwan turtle[x:2.000000, y:2.000000, name:turtle2]
[ INFO] [1692399646.697959476]: Spwan turtle successfully [name:turtle2]

X и y в журнале — это координаты второй сгенерированной черепахи с именем черепаха2. Имя:turtle2 во второй строке — это результат ответа конца Служить.

Соответствующий журнал также печатается в узле Turtlesim_node.

Язык кода:javascript
копировать
[ INFO] [1692399646.697808644]: Spawning turtle [turtle2] at x=[2.000000], y=[2.000000], theta=[0.000000]

Реализация Python

Перейдите в папку пакета

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_service

Создайте новую папку скриптов

Язык кода:javascript
копировать
mkdir scripts
cd scripts

Создадим то, что нам нужно Python документ

Язык кода:javascript
копировать
vim turtle_spawn.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура запросит /spawn Служить, Служить данные типа черепахисим::Spawn

import sys
import rospy
from turtlesim.srv import Spawn

def turtle_spawn():
    # Инициализировать узел ROS
    rospy.init_node('turtle_spawn')
    # После обнаружения /spawn Служить создайте клиент Служить и подключитесь к сервису с именем /spawn.
    rospy.wait_for_service('/spawn')
    try:
        add_turtle = rospy.ServiceProxy('/spawn',Spawn)
        # просить Служитьвызов        response = add_turtle(2.0, 2.0, 0.0, "turtle2")
        return response.name
    except rospy.ServiceException as e:
        print("Service call failed: %s"%e)

if __name__ == "__main__":
    # Показаны результаты для Служитьвызов
    print("Spwan turtle successfully [name:%s]" %(turtle_spawn()))

Дайте ему разрешение на изучение

Язык кода:javascript
копировать
chmod 777 turtle_spawn.py

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_spawn.py

Серверная реализация Сервиса

реализация на С++

Введите пакет функций Learning_service

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_service/src

Создайте нужные нам файлы C++.

Язык кода:javascript
копировать
vim turtle_command_server.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура будетосуществлять/turtle_commandСлужить,Служитьданныетипstd_srvs/Trigger */

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <std_srvs/Trigger.h>

using namespace ros;

Publisher turtle_vel_pub;
bool pubCommand = false;
//сервисная функция, входной параметр, выходные параметры
bool commandCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger:: Response &res) {
    pubCommand = !pubCommand;
    //Отображение данных запроса
    ROS_INFO("Publish turtle velocity command [%s]", pubCommand==true?"Yes":"No");
    //Устанавливаем данные обратной связи
    res.success = true;
    res.message = "Change turtle command state!";

    return true;
}

int main(int argc, char **argv) {
    //Инициализация узла ROS
    init(argc, argv, "turtle_command_server");
    //Создаем дескриптор узла
    NodeHandle n;
    //Создаем сервер с именем /turtle_command и регистрируем обратный вызов FunctioncommandCallback
    ServiceServer command_service = n.advertiseService("/turtle_command", commandCallback);
    //Создаем издателя, публикуем тему с именем /turtle1/cmd_vel, тип сообщения — geometry_msgs::Twist, длина очереди — 10
    turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);
    //Цикл ожидания функции обратного вызова
    ROS_INFO("Ready to receive turtle command.");
    //Устанавливаем частоту цикла
    Rate loop_rate(10);

    while(ok()) {
        //Просмотр очереди функции обратного вызова один раз
	spinOnce();
        //Если флаг верен, выдаем команду скорости
	if (pubCommand) {
	    geometry_msgs::Twist vel_msg;
	    vel_msg.linear.x = 0.5;
	    vel_msg.angular.z = 0.2;
	    turtle_vel_pub.publish(vel_msg);
	}
        //Задержка в зависимости от частоты цикла
	loop_rate.sleep();
    }

    return 0;
}

Это Служить, который получает просьбу заставить черепаху двигаться по кругу.

вернуться в learning_service папка, изменить CMakelists.txt。

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_command_server
rosservice call /turtle_command "{}"

После завершения изучения мы увидели, что маленькая черепаха постоянно двигалась кругами.

Когда мы отправим запрос еще раз

Язык кода:javascript
копировать
rosservice call /turtle_command "{}"

Детеныш черепахи перестанет двигаться.

Терминал Turtle_command_server Служить напечатает два таких журнала.

Язык кода:javascript
копировать
[ INFO] [1692495991.674337329]: Publish turtle velocity command [Yes]
[ INFO] [1692496732.674292008]: Publish turtle velocity command [No]

Здесь «Да» означает, что черепаха начинает двигаться, а «Нет» означает, что черепаха перестает двигаться.

Реализация Python

Перейдите в папку сценариев пакета.

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_service/scripts

Создадим то, что нам нужно Python документ

Язык кода:javascript
копировать
vim turtle_command_server.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура будетосуществлять/turtle_commandСлужить,Служитьданныетипstd_srvs/Triggerimport rospy
import _thread,time
from geometry_msgs.msg import Twist
from std_srvs.srv import Trigger,TriggerResponse

pubCommand = False
# Создайте издателя, опубликуйте тему с именем /turtle1/cmd_vel, тип сообщения — geometry_msgs::Twist, а длина очереди — 10.
turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)

def command_thread():
    while True:
        if pubCommand:
            vel_msg = Twist()
            vel_msg.linear.x = 0.5
            vel_msg.angular.z = 0.2
            turtle_vel_pub.publish(vel_msg)

        time.sleep(0.1)

# сервисная функция, входной параметр, выходные параметры
def commandCallback(req):
    global pubCommand
    pubCommand = bool(1 - pubCommand)
    # Показать запросыданные
    rospy.loginfo("Publish trutle velocity command![%d]", pubCommand)
    # Установить обратную связь
    return TriggerResponse(1, "Change turtle command state!")


def turtle_command_server():
    # Инициализация узла ROS
    rospy.init_node('turtle_command_server')
    # Создайте сервер с именем /turtle_command и зарегистрируйте обратный вызов FunctioncommandCallback.
    s = rospy.Service('/turtle_command', Trigger, commandCallback)
    # Цикл ожидания функции обратного вызова
    print("Ready to receive turtle command.")

    _thread.start_new_thread(command_thread, ())
    rospy.spin()

if __name__ == "__main__":

    turtle_command_server()

Предоставить разрешения на изучение

Язык кода:javascript
копировать
chmod 777 turtle_command_server.py

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_command_server.py
rosservice call /turtle_command "{}"

сноваосуществлять

Язык кода:javascript
копировать
rosservice call /turtle_command "{}"

В это время в конце Служить будет напечатано всего

Язык кода:javascript
копировать
[INFO] [1692498798.819324]: Publish trutle velocity command![1]
[INFO] [1692498830.254050]: Publish trutle velocity command![0]

Определение и использование сервисных данных

реализация на С++

Перейдите в папку пакета

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_service

Новыйданныедокументпапка

Язык кода:javascript
копировать
mkdir srv
cd srv

Создадим то, что нам нужноданныедокумент

Язык кода:javascript
копировать
vim Person.srv

Содержание следующее

Язык кода:javascript
копировать
string name
uint8 age
uint8 sex

uint8 unknown = 0
uint8 male    = 1
uint8 female  = 2
---
string result

Отличие от сообщения темы заключается в том, что документ данных содержит части запроса и ответа, разделенные --- посередине.

Установить правила компиляции

возвращаться learning_service папка, изменить package.xml, добавляет функциональные зависимости пакетов для динамически генерируемых программ.

Язык кода:javascript
копировать
cd ..
vim package.xml

добавить виз Содержание следующее

Язык кода:javascript
копировать
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

в <build_depend> длякомпилироватьполагаться,<exec_depend > дляосуществлятьполагаться。

Изменить CMakeLists.txt

Язык кода:javascript
копировать
vim CMakeLists.txt

Содержание следующее

Язык кода:javascript
копировать
find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
  message_generation
)

add_service_files(FILES Person.srv)
generate_messages(DEPENDENCIES std_msgs)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES learning_service
   CATKIN_DEPENDS geometry_msgs roscpp rospy std_msge turtlesim message_runtime
#  DEPENDS system_lib
)

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

В это время мы увидим еще три документа в разделе Documents/catkin_ws/devel/include/learning_serviceОглавление. Person.h , PersonRequest.h, PersonResponse.h, которые состоят из ROS Компилируется автоматически, нам нужно только использовать заголовочный документ Person.h при его использовании. Person.hСодержание следующее

Язык кода:javascript
копировать
// Generated by gencpp from file learning_service/Person.msg
// DO NOT EDIT!


#ifndef LEARNING_SERVICE_MESSAGE_PERSON_H
#define LEARNING_SERVICE_MESSAGE_PERSON_H

#include <ros/service_traits.h>


#include <learning_service/PersonRequest.h>
#include <learning_service/PersonResponse.h>


namespace learning_service
{

struct Person
{

typedef PersonRequest Request;
typedef PersonResponse Response;
Request request;
Response response;

typedef Request RequestType;
typedef Response ResponseType;

}; // struct Person
} // namespace learning_service


namespace ros
{
namespace service_traits
{


template<>
struct MD5Sum< ::learning_service::Person > {
  static const char* value()
  {
    return "c198113e7dd9cc5c9fd5f271c8479b39";
  }

  static const char* value(const ::learning_service::Person&) { return value(); }
};

template<>
struct DataType< ::learning_service::Person > {
  static const char* value()
  {
    return "learning_service/Person";
  }

  static const char* value(const ::learning_service::Person&) { return value(); }
};


// service_traits::MD5Sum< ::learning_service::PersonRequest> should match
// service_traits::MD5Sum< ::learning_service::Person >
template<>
struct MD5Sum< ::learning_service::PersonRequest>
{
  static const char* value()
  {
    return MD5Sum< ::learning_service::Person >::value();
  }
  static const char* value(const ::learning_service::PersonRequest&)
  {
    return value();
  }
};

// service_traits::DataType< ::learning_service::PersonRequest> should match
// service_traits::DataType< ::learning_service::Person >
template<>
struct DataType< ::learning_service::PersonRequest>
{
  static const char* value()
  {
    return DataType< ::learning_service::Person >::value();
  }
  static const char* value(const ::learning_service::PersonRequest&)
  {
    return value();
  }
};

// service_traits::MD5Sum< ::learning_service::PersonResponse> should match
// service_traits::MD5Sum< ::learning_service::Person >
template<>
struct MD5Sum< ::learning_service::PersonResponse>
{
  static const char* value()
  {
    return MD5Sum< ::learning_service::Person >::value();
  }
  static const char* value(const ::learning_service::PersonResponse&)
  {
    return value();
  }
};

// service_traits::DataType< ::learning_service::PersonResponse> should match
// service_traits::DataType< ::learning_service::Person >
template<>
struct DataType< ::learning_service::PersonResponse>
{
  static const char* value()
  {
    return DataType< ::learning_service::Person >::value();
  }
  static const char* value(const ::learning_service::PersonResponse&)
  {
    return value();
  }
};

} // namespace service_traits
} // namespace ros

#endif // LEARNING_SERVICE_MESSAGE_PERSON_H

PersonRequest.hСодержание следующее

Язык кода:javascript
копировать
// Generated by gencpp from file learning_service/PersonRequest.msg
// DO NOT EDIT!


#ifndef LEARNING_SERVICE_MESSAGE_PERSONREQUEST_H
#define LEARNING_SERVICE_MESSAGE_PERSONREQUEST_H


#include <string>
#include <vector>
#include <memory>

#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>


namespace learning_service
{
template <class ContainerAllocator>
struct PersonRequest_
{
  typedef PersonRequest_<ContainerAllocator> Type;

  PersonRequest_()
    : name()
    , age(0)
    , sex(0)  {
    }
  PersonRequest_(const ContainerAllocator& _alloc)
    : name(_alloc)
    , age(0)
    , sex(0)  {
  (void)_alloc;
    }



   typedef std::basic_string<char, std::char_traits<char>, typename std::allocator_traits<ContainerAllocator>::template rebind_alloc<char>> _name_type;
  _name_type name;

   typedef uint8_t _age_type;
  _age_type age;

   typedef uint8_t _sex_type;
  _sex_type sex;



// reducing the odds to have name collisions with Windows.h 
#if defined(_WIN32) && defined(unknown)
  #undef unknown
#endif
#if defined(_WIN32) && defined(male)
  #undef male
#endif
#if defined(_WIN32) && defined(female)
  #undef female
#endif

  enum {
    unknown = 0u,
    male = 1u,
    female = 2u,
  };


  typedef boost::shared_ptr< ::learning_service::PersonRequest_<ContainerAllocator> > Ptr;
  typedef boost::shared_ptr< ::learning_service::PersonRequest_<ContainerAllocator> const> ConstPtr;

}; // struct PersonRequest_

typedef ::learning_service::PersonRequest_<std::allocator<void> > PersonRequest;

typedef boost::shared_ptr< ::learning_service::PersonRequest > PersonRequestPtr;
typedef boost::shared_ptr< ::learning_service::PersonRequest const> PersonRequestConstPtr;

// constants requiring out of line definition

   

   

   



template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::learning_service::PersonRequest_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::learning_service::PersonRequest_<ContainerAllocator> >::stream(s, "", v);
return s;
}


template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator==(const ::learning_service::PersonRequest_<ContainerAllocator1> & lhs, const ::learning_service::PersonRequest_<ContainerAllocator2> & rhs)
{
  return lhs.name == rhs.name &&
    lhs.age == rhs.age &&
    lhs.sex == rhs.sex;
}

template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator!=(const ::learning_service::PersonRequest_<ContainerAllocator1> & lhs, const ::learning_service::PersonRequest_<ContainerAllocator2> & rhs)
{
  return !(lhs == rhs);
}


} // namespace learning_service

namespace ros
{
namespace message_traits
{





template <class ContainerAllocator>
struct IsMessage< ::learning_service::PersonRequest_<ContainerAllocator> >
  : TrueType
  { };

template <class ContainerAllocator>
struct IsMessage< ::learning_service::PersonRequest_<ContainerAllocator> const>
  : TrueType
  { };

template <class ContainerAllocator>
struct IsFixedSize< ::learning_service::PersonRequest_<ContainerAllocator> >
  : FalseType
  { };

template <class ContainerAllocator>
struct IsFixedSize< ::learning_service::PersonRequest_<ContainerAllocator> const>
  : FalseType
  { };

template <class ContainerAllocator>
struct HasHeader< ::learning_service::PersonRequest_<ContainerAllocator> >
  : FalseType
  { };

template <class ContainerAllocator>
struct HasHeader< ::learning_service::PersonRequest_<ContainerAllocator> const>
  : FalseType
  { };


template<class ContainerAllocator>
struct MD5Sum< ::learning_service::PersonRequest_<ContainerAllocator> >
{
  static const char* value()
  {
    return "b3f7ec37d11629ec3010e27635cf22a9";
  }

  static const char* value(const ::learning_service::PersonRequest_<ContainerAllocator>&) { return value(); }
  static const uint64_t static_value1 = 0xb3f7ec37d11629ecULL;
  static const uint64_t static_value2 = 0x3010e27635cf22a9ULL;
};

template<class ContainerAllocator>
struct DataType< ::learning_service::PersonRequest_<ContainerAllocator> >
{
  static const char* value()
  {
    return "learning_service/PersonRequest";
  }

  static const char* value(const ::learning_service::PersonRequest_<ContainerAllocator>&) { return value(); }
};

template<class ContainerAllocator>
struct Definition< ::learning_service::PersonRequest_<ContainerAllocator> >
{
  static const char* value()
  {
    return "string name\n"
"uint8 age\n"
"uint8 sex\n"
"\n"
"uint8 unknown = 0\n"
"uint8 male    = 1\n"
"uint8 female  = 2\n"
;
  }

  static const char* value(const ::learning_service::PersonRequest_<ContainerAllocator>&) { return value(); }
};

} // namespace message_traits
} // namespace ros

namespace ros
{
namespace serialization
{

  template<class ContainerAllocator> struct Serializer< ::learning_service::PersonRequest_<ContainerAllocator> >
  {
    template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
    {
      stream.next(m.name);
      stream.next(m.age);
      stream.next(m.sex);
    }

    ROS_DECLARE_ALLINONE_SERIALIZER
  }; // struct PersonRequest_

} // namespace serialization
} // namespace ros

namespace ros
{
namespace message_operations
{

template<class ContainerAllocator>
struct Printer< ::learning_service::PersonRequest_<ContainerAllocator> >
{
  template<typename Stream> static void stream(Stream& s, const std::string& indent, const ::learning_service::PersonRequest_<ContainerAllocator>& v)
  {
    s << indent << "name: ";
    Printer<std::basic_string<char, std::char_traits<char>, typename std::allocator_traits<ContainerAllocator>::template rebind_alloc<char>>>::stream(s, indent + "  ", v.name);
    s << indent << "age: ";
    Printer<uint8_t>::stream(s, indent + "  ", v.age);
    s << indent << "sex: ";
    Printer<uint8_t>::stream(s, indent + "  ", v.sex);
  }
};

} // namespace message_operations
} // namespace ros

#endif // LEARNING_SERVICE_MESSAGE_PERSONREQUEST_H

PersonResponse.hСодержание следующее

Язык кода:javascript
копировать
// Generated by gencpp from file learning_service/PersonResponse.msg
// DO NOT EDIT!


#ifndef LEARNING_SERVICE_MESSAGE_PERSONRESPONSE_H
#define LEARNING_SERVICE_MESSAGE_PERSONRESPONSE_H


#include <string>
#include <vector>
#include <memory>

#include <ros/types.h>
#include <ros/serialization.h>
#include <ros/builtin_message_traits.h>
#include <ros/message_operations.h>


namespace learning_service
{
template <class ContainerAllocator>
struct PersonResponse_
{
  typedef PersonResponse_<ContainerAllocator> Type;

  PersonResponse_()
    : result()  {
    }
  PersonResponse_(const ContainerAllocator& _alloc)
    : result(_alloc)  {
  (void)_alloc;
    }



   typedef std::basic_string<char, std::char_traits<char>, typename std::allocator_traits<ContainerAllocator>::template rebind_alloc<char>> _result_type;
  _result_type result;





  typedef boost::shared_ptr< ::learning_service::PersonResponse_<ContainerAllocator> > Ptr;
  typedef boost::shared_ptr< ::learning_service::PersonResponse_<ContainerAllocator> const> ConstPtr;

}; // struct PersonResponse_

typedef ::learning_service::PersonResponse_<std::allocator<void> > PersonResponse;

typedef boost::shared_ptr< ::learning_service::PersonResponse > PersonResponsePtr;
typedef boost::shared_ptr< ::learning_service::PersonResponse const> PersonResponseConstPtr;

// constants requiring out of line definition



template<typename ContainerAllocator>
std::ostream& operator<<(std::ostream& s, const ::learning_service::PersonResponse_<ContainerAllocator> & v)
{
ros::message_operations::Printer< ::learning_service::PersonResponse_<ContainerAllocator> >::stream(s, "", v);
return s;
}


template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator==(const ::learning_service::PersonResponse_<ContainerAllocator1> & lhs, const ::learning_service::PersonResponse_<ContainerAllocator2> & rhs)
{
  return lhs.result == rhs.result;
}

template<typename ContainerAllocator1, typename ContainerAllocator2>
bool operator!=(const ::learning_service::PersonResponse_<ContainerAllocator1> & lhs, const ::learning_service::PersonResponse_<ContainerAllocator2> & rhs)
{
  return !(lhs == rhs);
}


} // namespace learning_service

namespace ros
{
namespace message_traits
{





template <class ContainerAllocator>
struct IsMessage< ::learning_service::PersonResponse_<ContainerAllocator> >
  : TrueType
  { };

template <class ContainerAllocator>
struct IsMessage< ::learning_service::PersonResponse_<ContainerAllocator> const>
  : TrueType
  { };

template <class ContainerAllocator>
struct IsFixedSize< ::learning_service::PersonResponse_<ContainerAllocator> >
  : FalseType
  { };

template <class ContainerAllocator>
struct IsFixedSize< ::learning_service::PersonResponse_<ContainerAllocator> const>
  : FalseType
  { };

template <class ContainerAllocator>
struct HasHeader< ::learning_service::PersonResponse_<ContainerAllocator> >
  : FalseType
  { };

template <class ContainerAllocator>
struct HasHeader< ::learning_service::PersonResponse_<ContainerAllocator> const>
  : FalseType
  { };


template<class ContainerAllocator>
struct MD5Sum< ::learning_service::PersonResponse_<ContainerAllocator> >
{
  static const char* value()
  {
    return "c22f2a1ed8654a0b365f1bb3f7ff2c0f";
  }

  static const char* value(const ::learning_service::PersonResponse_<ContainerAllocator>&) { return value(); }
  static const uint64_t static_value1 = 0xc22f2a1ed8654a0bULL;
  static const uint64_t static_value2 = 0x365f1bb3f7ff2c0fULL;
};

template<class ContainerAllocator>
struct DataType< ::learning_service::PersonResponse_<ContainerAllocator> >
{
  static const char* value()
  {
    return "learning_service/PersonResponse";
  }

  static const char* value(const ::learning_service::PersonResponse_<ContainerAllocator>&) { return value(); }
};

template<class ContainerAllocator>
struct Definition< ::learning_service::PersonResponse_<ContainerAllocator> >
{
  static const char* value()
  {
    return "string result\n"
"\n"
;
  }

  static const char* value(const ::learning_service::PersonResponse_<ContainerAllocator>&) { return value(); }
};

} // namespace message_traits
} // namespace ros

namespace ros
{
namespace serialization
{

  template<class ContainerAllocator> struct Serializer< ::learning_service::PersonResponse_<ContainerAllocator> >
  {
    template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
    {
      stream.next(m.result);
    }

    ROS_DECLARE_ALLINONE_SERIALIZER
  }; // struct PersonResponse_

} // namespace serialization
} // namespace ros

namespace ros
{
namespace message_operations
{

template<class ContainerAllocator>
struct Printer< ::learning_service::PersonResponse_<ContainerAllocator> >
{
  template<typename Stream> static void stream(Stream& s, const std::string& indent, const ::learning_service::PersonResponse_<ContainerAllocator>& v)
  {
    s << indent << "result: ";
    Printer<std::basic_string<char, std::char_traits<char>, typename std::allocator_traits<ContainerAllocator>::template rebind_alloc<char>>>::stream(s, indent + "  ", v.result);
  }
};

} // namespace message_operations
} // namespace ros

#endif // LEARNING_SERVICE_MESSAGE_PERSONRESPONSE_H

Все они являются заголовками документа C++.

Создать терминал и клиент Служить

Входить learning_service исходный коддокументпапка

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_service/src

создавать Служитьконец

Язык кода:javascript
копировать
vim person_server.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура будетосуществлять/show_personСлужить,Служитьданныетипlearning_service::Person */

#include <ros/ros.h>
#include "learning_service/Person.h"

using namespace ros;
//сервисная функция, входной параметр, выходные параметры
bool personCallback(learning_service::Person::Request &req, learning_service::Person::Response &res) {
    //Отображение данных запроса
    ROS_INFO("Person: name:%s  age:%d  sex:%d", req.name.c_str(), req.age, req.sex);
    //Устанавливаем данные обратной связи
    res.result = "OK";

    return true;
}

int main(int argc, char **argv) {
    //Инициализация узла ROS
    init(argc, argv, "person_server");
    //Создаем дескриптор узла
    NodeHandle n;
    //Создаем сервер с именем /show_person и регистрируем обратный вызов FunctionpersonCallback
    ServiceServer person_service = n.advertiseService("/show_person", personCallback);
    //Цикл ожидания функции обратного вызова
    ROS_INFO("Ready to show person informtion");
    spin();

    return 0;
}

Создать клиента

Язык кода:javascript
копировать
vim person_client.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура запросит /show_personСлужить,Служитьданные типа Learning_service::Person
 */

#include <ros/ros.h>
#include "learning_service/Person.h"

using namespace ros;

int main(int argc, char **argv) {
    //Инициализируем узел ROS
    init(argc, argv, "person_client");
    //Создаем дескриптор узла
    NodeHandle node;
    //После обнаружения /show_person Служить создайте клиент Служить и подключитесь к сервису с именем /show_person
    service::waitForService("/show_person");
    ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");
    //Инициализируем Learning_service::Запрос данных пользователя
    learning_service::Person srv;
    srv.request.name = "Tom";
    srv.request.age = 20;
    srv.request.sex = learning_service::Person::Request::male;
    //просить Служитьвызов    ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]", srv.request.name.c_str(), srv.request.age, srv.request.sex);

    person_client.call(srv);
    //Показать результаты Служитьвызов
    ROS_INFO("Show person result: %s", srv.response.result.c_str());

    return 0;
}

вернуться в learning_serviceпапка, изменить CMakelists.txt

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
add_dependencies(person_server ${PROJECT_NAME}_gencpp)

add_executable(person_client src/person_client.cpp)
target_link_libraries(person_client ${catkin_LIBRARIES})
add_dependencies(person_client ${PROJECT_NAME}_gencpp)

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun learning_service person_client
rosrun learning_service person_server

изучить Завершить в клиентевозвращаться

Язык кода:javascript
копировать
[ INFO] [1692650896.468258699]: waitForService: Service [/show_person] has not been advertised, waiting...
[ INFO] [1692650916.053619203]: waitForService: Service [/show_person] is now available.
[ INFO] [1692650916.053701403]: Call service to show person[name:Tom, age:20, sex:1]
[ INFO] [1692650916.055466855]: Show person result: OK

Распечатать журналы на стороне Служить

Язык кода:javascript
копировать
[ INFO] [1692650916.045710322]: Ready to show person informtion
[ INFO] [1692650916.055297356]: Person: name:Tom  age:20  sex:1

Реализация Python

Перейдите в папку сценариев пакета.

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_service/scripts

создавать Служитьконец

Язык кода:javascript
копировать
vim person_server.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура будетосуществлять/show_personСлужить,Служитьданныетипlearning_service::Personimport rospy
from learning_service.srv import Person, PersonResponse

# сервисная функция, входной параметр, выходные параметры
def personCallback(req):
    # Показать запросыданные
    rospy.loginfo("Person: name:%s  age:%d   sex:%d", req.name, req.age, req.sex)
    # Установить обратную связь
    return PersonResponse("OK")

def person_server():
    # Инициализация узла ROS
    rospy.init_node('person_server')
    # Создайте сервер с именем /show_person и зарегистрируйте функцию обратного вызова FunctionpersonCallback.
    s = rospy.Service('/show_person', Person, personCallback)
    # Цикл ожидания функции обратного вызова
    print("Ready to show person informtion")
    rospy.spin()

if __name__ == "__main__":

    person_server()

Создать клиента

Язык кода:javascript
копировать
vim person_client.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура запросит /show_personСлужить,Служитьданные типа Learning_service::Person

import sys
import rospy
from learning_service.srv import Person, PersonRequest

def person_client():
    # Инициализировать узел ROS
    rospy.init_node('person_client')
    # После обнаружения /show_person Служить создайте клиент Служить и подключитесь к сервису с именем /show_person.
    rospy.wait_for_service('/show_person')
    try:
        person_client = rospy.ServiceProxy('/show_person',Person)
        # просить Служитьвызов,входитьпроситьданные        response = person_client("Tom", 20, PersonRequest.male)
        return response.result
    except rospy.ServiceException as e:
        print("Service call failed: %s"%e)

if __name__ == "__main__":
    # Показаны результаты для Служитьвызов
    print("Show person result : %s" %(person_client()))

Дайте им разрешение

Язык кода:javascript
копировать
chmod 777 person_server.py 
chmod 777 person_client.py

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun learning_service person_client.py
rosrun learning_service person_server.py

Использование параметров и методы программирования

в РОС Мастер среднего размера с одним параметром. Утилита — Параметр. Сервер — глобальный словарь, используемый для сохранения конфигурации каждого узла. На картинке выше робот сохраняет три значения — имя робота, радиус и высоту. Эти параметры доступны глобально для всех узлов. Например, в узле Если А хочет запросить имя робота, оно будет отправлено в ROS. Мастер отправляет запрос и получает результат от my_robot. Таким образом можно обработать все узлы.

параметр Служитьустройство Использование

  • Использование командной строки

Сначала запустите ROS Master и узел эмулятора маленькой черепахи.

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node

вход

Язык кода:javascript
копировать
rosparam

возвращаться

Язык кода:javascript
копировать
rosparam is a command-line tool for getting, setting, and deleting parameters from the ROS Parameter Server.

Commands:
	rosparam set	set parameter
	rosparam get	get parameter
	rosparam load	load parameters from file
	rosparam dump	dump parameters to file
	rosparam delete	delete parameter
	rosparam list	list parameter names

Указывает, что команда, имеющая этот параметр, может быть установлена.

Запросить, сколько узлов параметров имеется

Язык кода:javascript
копировать
rosparam list

возвращаться

Язык кода:javascript
копировать
/rosdistro
/roslaunch/uris/host_guanjian_x99__40731
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r

в

Язык кода:javascript
копировать
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r

Представляет цвет фона симулятора черепахи.

Язык кода:javascript
копировать
/rosdistro
/roslaunch/uris/host_guanjian_x99__40731
/rosversion
/run_id

для РОС Мастер сам предлагает параметр,可以поставлятьROSизномер версии,Идентификатор запущенного процесса.

Получите значение B в RGB цвета фона эмулятора маленькой черепахи.

Язык кода:javascript
копировать
rosparam get /turtlesim/background_b

возвращаться

Язык кода:javascript
копировать
255

Получите значение G в RGB цвета фона эмулятора маленькой черепахи.

Язык кода:javascript
копировать
rosparam get /turtlesim/background_g

возвращаться

Язык кода:javascript
копировать
86

Получите значение R в цвете фона RGB эмулятора маленькой черепахи.

Язык кода:javascript
копировать
rosparam get /turtlesim/background_r

возвращаться

Язык кода:javascript
копировать
69

Получить дистрибутив ROS

Язык кода:javascript
копировать
rosparam get /rosdistro

возвращаться

Язык кода:javascript
копировать
'noetic

  '

Получить номер версии ROS

Язык кода:javascript
копировать
rosparam get /rosversion

возвращаться

Язык кода:javascript
копировать
'1.16.0

  '

Измените значение B цвета фона RGB эмулятора маленькой черепахи.

Язык кода:javascript
копировать
rosparam set /turtlesim/background_b 100

Здесь нам нужно обратить внимание на,Хотя мы изменили цвет фона,Но это вступит в силу не сразу.,Нам нужно отправить запрос на Служить, чтобы узел эмулятора черепахи перечитал параметр.

Язык кода:javascript
копировать
rosservice call /clear "{}"

В это время меняется цвет фона эмулятора маленькой черепахи.

ВоляparameterSluzhitkeiwareпараметр сохранить как документ

Язык кода:javascript
копировать
rosparam dump param.yaml

После сохранениядокументиз Содержание следующее

Язык кода:javascript
копировать
rosdistro: 'noetic

  '
roslaunch:
  uris:
    host_guanjian_x99__40731: http://guanjian-X99:40731/
rosversion: '1.16.0

  '
run_id: b1762296-4477-11ee-98d0-8defeaece2a0
turtlesim:
  background_b: 100
  background_g: 86
  background_r: 69

мы можем Исправлять Должендокумент,Затем перезагрузите его обратно в параметр Служитьустройство中 . Например, меняем значения RGB узлов эмулятора черепахи на 0.

Язык кода:javascript
копировать
rosdistro: 'noetic

  '
roslaunch:
  uris:
    host_guanjian_x99__40731: http://guanjian-X99:40731/
rosversion: '1.16.0

  '
run_id: b1762296-4477-11ee-98d0-8defeaece2a0
turtlesim:
  background_b: 0
  background_g: 0
  background_r: 0

загрузить

Язык кода:javascript
копировать
rosparam load param.yaml

Отправить запрос Служить еще раз

Язык кода:javascript
копировать
rosservice call /clear "{}"

На этом этапе мы видим, что цвет фона эмулятора маленькой черепахи изменился на черный.

Удаляем определенный параметр, например удаляем background_g

Язык кода:javascript
копировать
rosparam delete /turtlesim/background_g

На этом этапе мы читаем список параметров

Язык кода:javascript
копировать
rosparam list

возвращаться

Язык кода:javascript
копировать
/rosdistro
/roslaunch/uris/host_guanjian_x99__40731
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_r

Отправить запрос Служить еще раз

Язык кода:javascript
копировать
rosservice call /clear "{}"

Цвет фона эмулятора черепахи также изменится соответствующим образом.

  • Разработка программирования(реализация на С++)

Войти в рабочую область

Язык кода:javascript
копировать
cd Documents/catkin_ws/src

Создать новый пакет

Язык кода:javascript
копировать
catkin_create_pkg learning_parameter roscpp rospy std_srvs

В пакете функций Входитьlearning_parameter

Язык кода:javascript
копировать
cd learning_parameter/src

Создайте нужные нам файлы C++.

Язык кода:javascript
копировать
vim parameter_config.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура устанавливает/считывает параметр в процедуре маленькой черепахи.
 */

#include <string>
#include <ros/ros.h>
#include <std_srvs/Empty.h>

using namespace ros;

int main(int argc, char **argv) {
    int red, green, blue;
    //Инициализация узла ROS
    init(argc, argv, "parameter_config");
    //Создаем дескриптор узла
    NodeHandle node;
    //Читаем параметр цвета фона
    param::get("/turtlesim/background_r", red);
    param::get("/turtlesim/background_g", green);
    param::get("/turtlesim/background_b", blue);

    ROS_INFO("Get Background Color[%d, %d, %d]", red, green, blue);
    //Устанавливаем параметр цвета фона
    param::set("/turtlesim/background_r", 255);
    param::set("/turtlesim/background_g", 255);
    param::set("/turtlesim/background_b", 255);

    ROS_INFO("Set Background Color[255, 255, 255]");
    //Читаем параметр цвета фона
    param::get("/turtlesim/background_r", red);
    param::get("/turtlesim/background_g", green);
    param::get("/turtlesim/background_b", blue);

    ROS_INFO("Re-get Background Color[%d, %d, %d]", red, green, blue);
    //вызов Служить, обновить цвет фона
    service::waitForService("/clear");
    ServiceClient clear_background = node.serviceClient<std_srvs::Empty>("/clear");
    std_srvs::Empty srv;
    clear_background.call(srv);

    sleep(1);

    return 0;
}

вернуться в learning_parameterпапка, изменить CMakelists.txt。

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
add_executable(parameter_config src/parameter_config.cpp)
target_link_libraries(parameter_config ${catkin_LIBRARIES})

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_parameter parameter_config

возвращаться

Язык кода:javascript
копировать
[ INFO] [1693175924.083145386]: Get Background Color[69, 86, 255]
[ INFO] [1693175924.086266645]: Set Background Color[255, 255, 255]
[ INFO] [1693175924.087441186]: Re-get Background Color[255, 255, 255]

И цвет фона окна эмулятора черепахи изменится на белый.

  • Разработка программирования(Реализация Python)

Перейдите в папку пакета,并создавать脚本документпапка,Входить Должендокументпапка

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_parameter
mkdir scripts
cd scripts

Создадим то, что нам нужно Python документ

Язык кода:javascript
копировать
vim parameter_config.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура устанавливает/считывает параметр в процедуре маленькой черепахи.

import sys
import rospy
from std_srvs.srv import Empty

def parameter_config():
    # Инициализация узла ROS
    rospy.init_node('parameter_config', anonymous=True)
    # Чтение параметра цвета фона
    red = rospy.get_param('/turtlesim/background_r')
    green = rospy.get_param('/turtlesim/background_g')
    blue = rospy.get_param('/turtlesim/background_b')

    rospy.loginfo("Get Backgroud Color[%d, %d, %d]", red, green, blue)
    # Установить параметр цвета фона
    rospy.set_param("/turtlesim/background_r", 255)
    rospy.set_param("/turtlesim/background_g", 255)
    rospy.set_param("/turtlesim/background_b", 255)
    # Чтение параметра цвета фона
    red = rospy.get_param('/turtlesim/background_r')
    green = rospy.get_param('/turtlesim/background_g')
    blue = rospy.get_param('/turtlesim/background_b')

    rospy.loginfo("Get Backgroud Color[%d, %d, %d]", red, green, blue)
    # вызвать Служить, обновить цвет фона
    rospy.wait_for_service('/clear')
    try:
        clear_background = rospy.ServiceProxy('/clear', Empty)

        response = clear_background()
        return response
    except rospy.ServiceException as e:
        print("Service call failed: %s"%e)

if __name__ == "__main__":

    parameter_config()

Предоставить разрешения на изучение

Язык кода:javascript
копировать
chmod 777 parameter_config.py

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_parameter parameter_config.py

Система управления трансформацией координат

Преобразование координат положения робота представляет собой серию матричных операций 4*4.,Подробную информацию см.Подбор баллов знаний SLAMвЖесткое движение тела

Преобразование координат TF

TF — это инструмент в ROS, который обеспечивает операции преобразования координат робота.

  1. 5 секунд назад, какова была связь между системой координат головы робота и глобальной системой координат?
  2. Где находится положение объекта, захваченного роботом, относительно центральной системы координат робота?
  3. Где находится положение системы координат центра робота относительно глобальной системы координат?

Как достичь

  1. Преобразование вещательного TF
  2. Мониторинг трансформации ТФ

Это не та тема Тема и Служить Сервис, о которой мы говорили ранее. После запуска ROS Master и TF в фоновом режиме будет поддерживаться так называемое дерево TF. Все системы координат сохраняются в дереве TF посредством этой древовидной структуры. Если какой-либо узел хочет запросить отношение преобразования между любыми двумя системами координат, его можно запросить напрямую через дерево TF.

Крайнее левое изображение выше — робот.,Красная часть — это шасси робота.,Сделаем систему координат в центральной точке,Назовите это base_link. На шасси имеется лазерный радар,Лидару необходимо излучать радиолокационные сигналы для получения информации о глубине.,Также создадим систему координат в центральной части. Объекты, обнаруженные лидаром, основаны на их положении в этой системе координат.,Эта система координат называется base_laser. На среднем рисунке показано соотношение перемещения между двумя системами координат — на 20 см вверх и вниз.,Слева и справа 10 см.,Между ними нет ротационной связи. На картинке крайний справа,Когда лидар обнаруживает стену перед собой,Расстояние 0,3 метра,На этом этапе нам нужно преобразовать его в координаты в системе координат base_link.,Это можно получить через TF. Обычно мы фокусируемся на расстоянии системы координат base_link.,Вместо расстояния base_laser. через трансформацию ТФ,Мы знаем, что стена находится на 0,4 метра ниже base_link. Метод трансформации заключается в следующем.

Пример преобразования координат

Установите компонент преобразования координат черепахи.

Язык кода:javascript
копировать
sudo apt-get install ros-noetic-turtle-tf

Если это Убунту Система 18.04

Язык кода:javascript
копировать
sudo apt-get install ros-melodic-turtle-tf

Замените нашу среду conda. Эта среда должна соответствовать нашей предыдущей среде программирования Python и установить numpy.

Язык кода:javascript
копировать
conda activate py39
pip install numpy

запустить сценарий,Это документ-скрипт,Вы можете запустить много узлов одновременно

Язык кода:javascript
копировать
roslaunch turtle_tf turtle_tf_demo.launch

После завершения запуска,Мы увидим окно с двумя черепашками.,И сделать так, чтобы одна черепашка подошла к другой черепахе.

Запустите узел управления кнопкой маленькой черепахи.

Язык кода:javascript
копировать
rosrun turtlesim turtle_teleop_key

В это время мы с помощью клавиатуры перемещаем маленькую черепаху, а другая маленькая черепаха последует за ней.

Чтобы отслеживать информацию маленькой черепахи, откройте новый терминал, а также необходимо переключить среду конды.

Язык кода:javascript
копировать
conda activate py39
rosrun tf view_frames

После запуска он сообщит

Язык кода:javascript
копировать
TypeError: cannot use a string pattern on a bytes-like object

Это связано с тем, что в исходном коде функционального документа используется Python 2, а в нашей среде — Python 3. Поэтому нам нужно изменить

Язык кода:javascript
копировать
sudo vim /opt/ros/noetic/lib/tf/view_frames

Измененный контент

Язык кода:javascript
копировать
vstr = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[1]
vstr = str(vstr)

в то же время Исправлятьдокументпапка和view_framesМестоиметь ВОЗ

Язык кода:javascript
копировать
sudo chown user:user /opt/ros/noetic/lib/tf
sudo chown user:user /opt/ros/noetic/lib/tf/view_frames

Повторный запуск

Язык кода:javascript
копировать
rosrun tf view_frames

Два новых документа будут созданы в папке /opt/ros/noetic/lib/tf.

Язык кода:javascript
копировать
frames.gv
frames.pdf

Здесь мы в основном рассматриваем документ framework.pdf.

Это означает, что в текущем симуляторе есть три системы координат.,Один - мир,Это глобальная система координат,Он представляет собой начало координат всего симулятора. Эта координатная точка никогда не будет перемещаться. Две другие системы координат,Одного зовут черепаха1,Один называется tutle2,Они расположены на двух черепашках. Turtle1 и Tutle2 продолжат перекрываться.,Но по сравнению с миром он постоянно меняется.

  • Инструменты командной строки
Язык кода:javascript
копировать
rosrun tf tf_echo turtle1 turtle2

Черепаха1 и черепаха2 здесь представляют две системы координат.

В это время, когда мы используем клавиатуру для управления движением маленькой черепахи, инструмент записывает преобразование между двумя системами координат.

Язык кода:javascript
копировать
At time 1693616316.041
- Translation: [-0.909, 1.462, 0.000]
- Rotation: in Quaternion [0.000, 0.000, -0.548, 0.837]
            in RPY (radian) [0.000, -0.000, -1.160]
            in RPY (degree) [0.000, -0.000, -66.444]
At time 1693616317.049
- Translation: [-2.223, 0.791, 0.000]
- Rotation: in Quaternion [0.000, 0.000, -0.225, 0.974]
            in RPY (radian) [0.000, 0.000, -0.454]
            in RPY (degree) [0.000, 0.000, -25.995]
At time 1693616318.041
- Translation: [-1.314, 1.677, 0.000]
- Rotation: in Quaternion [0.000, 0.000, -0.496, 0.868]
            in RPY (radian) [0.000, 0.000, -1.038]
            in RPY (degree) [0.000, 0.000, -59.484]
At time 1693616319.049
- Translation: [-2.085, 0.923, 0.000]
- Rotation: in Quaternion [0.000, 0.000, -0.232, 0.973]
            in RPY (radian) [0.000, 0.000, -0.469]
            in RPY (degree) [0.000, 0.000, -26.852]
At time 1693616320.041
- Translation: [-1.256, 0.547, 0.000]
- Rotation: in Quaternion [0.000, 0.000, -0.204, 0.979]
            in RPY (radian) [0.000, 0.000, -0.412]
            in RPY (degree) [0.000, 0.000, -23.582]
At time 1693616321.049
- Translation: [-0.749, 0.326, 0.000]
- Rotation: in Quaternion [0.000, 0.000, -0.204, 0.979]
            in RPY (radian) [0.000, 0.000, -0.411]
            in RPY (degree) [0.000, 0.000, -23.544]

Здесь описано, как система координат черепахи2 становится системой координат черепахи1 посредством преобразования. Он разделен на две части — Трансляция и Ротация.

Три значения Translation представляют x,y,z三个坐标上из平移,Три выражения вращенияиметь,Первый — Кватернион (кватернион),иметьзакрывать四元数из概念可以参考Подбор баллов знаний SLAMвКватернионы.Второй — в радианах.описыватьизRPY,то есть через ось X,ось Y,zось для вращения。Третий – через угловой блокописыватьизRPY。

  • Инструменты визуализации
Язык кода:javascript
копировать
rosrun rviz rviz -d `rospack find turtle_tf`/rviz/turtle_rviz.rviz

После открытия вам нужно изменить «Фиксированный кадр» на «Мир», затем нажать кнопку «Добавить», чтобы добавить опцию TF. В это время, если мы будем использовать клавиатуру для управления движением маленькой черепахи, мы увидим, что система координат черепахи2 в инструменте rviz постоянно перемещается в систему координат черепахи1.

Начало координат в середине сетки,Это начало мировых координат,С левой стороны есть две точки: красная и зеленая.,Это две системы координат черепаха1 и черепаха2.

Программная реализация трансляции и мониторинга системы координат ТФ

  • реализация на С++

Войти в рабочую область

Язык кода:javascript
копировать
cd Documents/catkin_ws/src

Создать новый пакет функций

Язык кода:javascript
копировать
catkin_create_pkg learning_tf roscpp rospy tf turtlesim

Введите каталог src пакета функций.

Язык кода:javascript
копировать
cd learning_tf/src

Создадим то, что нам нужно广播устройствоC++документ

Язык кода:javascript
копировать
vim turtle_tf_broadcaster.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура генерирует tfданные, вычисляет и выдает команду скорости черепахи2.
 */

#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <turtlesim/Pose.h>
#include <string>

using namespace ros;
using namespace std;

string turtle_name;

void poseCallback(const turtlesim::PoseConstPtr& msg) {
    //Создаем вещательную компанию tf
    static tf::TransformBroadcaster br;
    //Инициализируем tfданные
    //transform — матрица преобразования координат
    tf::Transform transform;
    //Перенос координат, преобразование перемещения черепахи1 относительно мира вокруг осей координат x, y, z
    transform.setOrigin(tf::Vector3(msg->x, msg->y, 0.0));
    //Кватернион
    tf::Quaternion q;
    //Вращение координат, преобразование вращения черепахи1 вокруг осей координат x, y и z относительно мира
    q.setRPY(0, 0, msg->theta);
    transform.setRotation(q);
    //Трансляция тфданных между миром и системой координат черепахи черепаха1
    //Дерево tf в фоновом режиме вставит в него широковещательные данные
    br.sendTransform(tf::StampedTransform(transform, Time::now(), "world", turtle_name));
}

int main(int argc, char** argv) {
    //Инициализируем узел ROS
    init(argc, argv, "my_tf_broadcaster");
    //параметр входа как имя для черепахи
    if (argc != 2) {
	ROS_ERROR("need turtle name as argument");
	return -1;
    }
    turtle_name = argv[1];
    //Подписываемся на позицию черепахи в теме
    NodeHandle node;
    Subscriber sub = node.subscribe(turtle_name + "/pose", 10, &poseCallback);
    //Цикл ожидания функции обратного вызова
    spin();

    return 0;
}

Снова Создадим то, что нам нужно监听устройствоC++документ

Язык кода:javascript
копировать
vim turtle_tf_listener.cpp

Содержание следующее

Язык кода:javascript
копировать
/*
 * Эта процедура отслеживает tfданные, вычисляет и выдает инструкции скорости черепахи2.
 */

#include <ros/ros.h>
#include <tf/transform_listener.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Spawn.h>

using namespace ros;

int main(int argc, char** argv) {
    //Инициализируем узел ROS
    init(argc, argv, "my_tf_listener");
    //Создаем дескриптор узла
    NodeHandle node;
    //Запрос на создание новой черепахи черепахи2
    service::waitForService("/spawn");
    ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");
    turtlesim::Spawn srv;
    add_turtle.call(srv);
    //Создаем издатель, который публикует инструкции по управлению скоростью черепахи2, чтобы заставить новую черепаху двигаться.
    Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel", 10);
    //Создаем прослушиватель tf
    tf::TransformListener listener;

    Rate rate(10.0);
    while(node.ok()) {
        //Получаем tfданные между системами координат черепахи1 и черепахи2
	tf::StampedTransform transform;
	try {
            //Ожидание преобразования, есть ли в системе две системы координат черепаха1 и черепаха2, ждем 3 секунды
	    listener.waitForTransform("/turtle2", "/turtle1", Time(0), Duration(3.0));
            //Преобразование запроса, если между запросом двух систем координат существует связь, результаты запроса сохраняются в преобразовании
	    listener.lookupTransform("/turtle2", "/turtle1", Time(0), transform);
	} catch (tf::TransformException &ex) {
	    ROS_ERROR("%s", ex.what());
	    Duration(1.0).sleep();
	    continue;
	}
        //В соответствии с позиционным соотношением между системами координат черепахи1 и черепахи2, выдаем команду управления скоростью черепахи2, чтобы позволить черепахе 2 двигаться к черепахе 1
	geometry_msgs::Twist vel_msg;
        //угловая скорость
	vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(), transform.getOrigin().x());
        //скорость линии
	vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) + pow(transform.getOrigin().y(), 2));
	turtle_vel.publish(vel_msg);

	rate.sleep();
    }
    return 0;
}

вернуться в learning_tf папка, изменить CMakelists.txt。

Язык кода:javascript
копировать
cd ..
vim CMakelists.txt

добавить в Содержание следующее

Язык кода:javascript
копировать
add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp)
target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES})

add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../..
catkin_make

изучить Программа, в другом окне терминала изучить

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_tf turtle_tf_broadcaster __name:=turtle1_tf_broadcaster /turtle1
rosrun learning_tf turtle_tf_broadcaster __name:=turtle2_tf_broadcaster /turtle2
rosrun learning_tf turtle_tf_listener
rosrun turtlesim turtle_teleop_key

Управляя клавиатурой и перемещая первую черепашку, мы обнаружим, что вторая черепашка следует за ней.

  • Реализация Python

Перейдите в папку пакета

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_tf

Создайте новую папку скриптов

Язык кода:javascript
копировать
mkdir scripts
cd scripts

Создадим то, что нам нужен вещатель Python документ

Язык кода:javascript
копировать
vim turtle_tf_broadcaster.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура генерирует tfданные, вычисляет и выдает команду скорости черепахи2.

import roslib
roslib.load_manifest('learning_tf')
import rospy
import tf
import turtlesim.msg
import sys

def handle_turtle_pose(msg, turtlename):
    # Создать вещательную компанию tf
    br = tf.TransformBroadcaster()
    # Трансляция тфданных между миром и системой координат черепахи черепаха1
    br.sendTransform((msg.x, msg.y, 0), tf.transformations.quaternion_from_euler(0, 0, msg.theta), rospy.Time.now(), turtlename, "world")

if __name__ == '__main__':
    # Инициализировать узел ROS
    rospy.init_node(sys.argv[1])
    # параметр вхождения как имя для черепахи
    turtlename = sys.argv[2]
    # Подписаться на тему «Поза черепахи»
    rospy.Subscriber('/%s/pose' % turtlename, turtlesim.msg.Pose, handle_turtle_pose, turtlename)
    # Цикл ожидания функции обратного вызова
    rospy.spin()

Снова Создадим то, что нам нужно监听устройствоPythonдокумент

Язык кода:javascript
копировать
vim turtle_tf_listener.py

Содержание следующее

Язык кода:javascript
копировать
#!/home/user/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-
# Эта процедура отслеживает tfданные, вычисляет и выдает инструкции скорости черепахи2.

import roslib
roslib.load_manifest('learning_tf')
import rospy
import math
import tf
import geometry_msgs.msg
import turtlesim.srv

if __name__ == '__main__':
    # Инициализировать узел ROS
    rospy.init_node('turtle_tf_listener')
    # Создать прослушиватель tf
    listener = tf.TransformListener()
    # Запрос на создание новой черепахи черепаха2
    rospy.wait_for_service('/spawn')
    spawner = rospy.ServiceProxy('/spawn', turtlesim.srv.Spawn)
    spawner(4, 2, 0, 'turtle2')
    # Создайте издателя, который будет публиковать инструкции по управлению скоростью черепахи2, чтобы заставить новых черепах двигаться.
    turtle_vel = rospy.Publisher('turtle2/cmd_vel', geometry_msgs.msg.Twist, queue_size=1)

    rate = rospy.Rate(10.0)
    while not rospy.is_shutdown():
        try:
            # Преобразование запроса. Если между запросом двух систем координат существует связь, результаты запроса сохраняются в транс.
            trans, rot = listener.lookupTransform('/turtle2', '/turtle1', rospy.Time(0))
        except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
            continue
        # В соответствии с позиционным соотношением между системами координат черепахи 1 и черепахи 2, выдайте команду управления скоростью черепахи 2, чтобы позволить черепахе 2 двигаться к черепахе 1.
        angular = 4 * math.atan2(trans[1], trans[0])
        linear = 0.5 * math.sqrt(trans[0]**2 + trans[1]**2)
        cmd = geometry_msgs.msg.Twist()
        cmd.linear.x = linear
        cmd.angular.z = angular
        turtle_vel.publish(cmd)

        rate.sleep()

Установить разрешения

Язык кода:javascript
копировать
chmod 777 turtle_tf_broadcaster.py
chmod 777 turtle_tf_listener.py

осуществлять Заказ (разные окна терминала)

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun learning_tf turtle_tf_broadcaster.py turtle1_tf_broadcaster turtle1
rosrun learning_tf turtle_tf_broadcaster.py turtle2_tf_broadcaster turtle2
rosrun learning_tf turtle_tf_listener.py
rosrun turtlesim turtle_teleop_key

запустить файл запуска

грамматика

Запуск документа: Конфигурация и запуск нескольких узлов через XML-документ (может автоматически запускать ROS Master)

Язык кода:javascript
копировать
<launch>
    <node pkg="turtlesim" name="sim1" type="turtlesim_node" />
    <node pkg="turtlesim" name="sim2" type="turtlesim_node" />
</launch>

этотв<launch>является корневым узлом。

  • <node>для启动节点
  • pkg: имя пакета функций, в котором расположен узел.
  • тип: возможное имя узла.
  • name: имя узла во время его работы.
  • вывод: печатать ли информацию журнала на терминале
  • respawn: если процесс узла зависает, следует ли его перезапустить.
  • обязательно: узлы, которые необходимо запустить
  • ns: пространство имен, чтобы избежать конфликтов имен.
  • args: параметр времени выполнения

âПервые три атрибута являются наиболее основными атрибутами, а следующие атрибуты являются необязательными.

  • <param>для设置ROSсистемабегатьвпараметр,Он хранится в параметреServer
Язык кода:javascript
копировать
<param name="output_frame" value="odom" />
  1. name:параметримя
  2. значение:параметрценить
  3. <rosparam>нагрузкапараметрдокументв多个параметр
Язык кода:javascript
копировать
<rosparam file="params.yaml" command="load" ns="params" />
  • <arg>launchдокумент内部из局部变量,Только для использования в стартовом документе
Язык кода:javascript
копировать
<arg name="arg-name" default="arg-value" />
  1. name:параметримя
  2. значение:параметрценить

вызов

Язык кода:javascript
копировать
<param name="foo" value="$(arg arg-name)" />
<node name="node" pkg="package" type="type" args="$(arg arg-name)" />

Оба вызова здесь являются одним и тем же аргументом вызова. Они не имеют ничего общего друг с другом.

  • <remap>переназначитьROS计算图资源из命имя
Язык кода:javascript
копировать
<remap from="/turtlebot/cmd_vel" to="/cmd_vel" />
  1. откуда: оригинальное название
  2. to: присвоение имени после сопоставления

Здесь следует отметить, что при переназначении,Тогда исходное имя больше не существует,Только имя после отображения.

  • <include>Вложенный,Содержит другой документ запуска,Подобно заголовку документа на языке C, он содержит
Язык кода:javascript
копировать
<include file="$(dirname)/other.launch" />

файл: включены другие пути к запускаемым документам

Больше тегов можно найтиhttps://wiki.ros.org/roslaunch/XML

действовать

Войти в рабочую область

Язык кода:javascript
копировать
cd Documents/catkin_ws/src

Создать новый пакет функций, здесь нам не нужны никакие зависимости

Язык кода:javascript
копировать
catkin_create_pkg learning_launch

Войдите в пакет функций и создайте папку запуска документов.

Язык кода:javascript
копировать
cd learning_launch
mkdir launch
cd launch

Создадим то, что нам нужнопервыйlaunchдокумент

Язык кода:javascript
копировать
vim simple.launch

Содержание следующее

Язык кода:javascript
копировать
<launch>
    <node pkg="learning_topic" type="person_subscriber" name="talker" output="screen" />
    <node pkg="learning_topic" type="person_publisher" name="listener" output="screen" />
</launch>

Вернитесь в папку catkin_ws и начните компилировать.

Язык кода:javascript
копировать
cd ../../..
catkin_make

запуск документа запуска

Язык кода:javascript
копировать
roslaunch learning_launch simple.launch

бревновыход

Язык кода:javascript
копировать
... logging to /home/guanjian/.ros/log/8f043736-4a15-11ee-94ed-eb1c4a5ce82f/roslaunch-guanjian-X99-4414.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://guanjian-X99:43073/

SUMMARY
========

PARAMETERS
 * /rosdistro: noetic
 * /rosversion: 1.16.0

NODES
  /
    listener (learning_topic/person_publisher)
    talker (learning_topic/person_subscriber)

auto-starting new master
process[master]: started with pid [4426]
ROS_MASTER_URI=http://localhost:11311

setting /run_id to 8f043736-4a15-11ee-94ed-eb1c4a5ce82f
process[rosout-1]: started with pid [4436]
started core service [/rosout]
process[talker-2]: started with pid [4439]
process[listener-3]: started with pid [4440]
[ INFO] [1693716695.734350100]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1693716696.734435776]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1693716696.734844895]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1693716697.734414495]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1693716697.734667411]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1693716698.734408905]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1693716698.734658015]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1693716699.734416177]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1693716699.734658584]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1693716700.734417712]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1693716700.734663411]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1693716701.734412627]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1693716701.734663706]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1693716702.734420615]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1693716702.734660215]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1693716703.734366533]: Publish Person Info: name:Tom age:18 sex:1

Здесь мы видим, что оба узла работают в одном терминале. Это пример предыдущего издателя и подписчика. Издатель сначала публикует информацию о человеке, а подписчик получает сообщение и печатает информацию о человеке.

вернуться в папку запуска_документа вlearning_launch, создав второй файл запуска

Язык кода:javascript
копировать
cd src/learning_launch/launch
vim turtlesim_parameter_config.launch

Содержание следующее

Язык кода:javascript
копировать
<launch>
    <param name="/turtle_number" value="2" />

    <node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node">
        <param name="turtle_name1" value="Tom" />
        <param name="trutle_name2" value="Jerry" />

        <rosparam file="$(find learning_launch)/config/param.yaml" command="load" />
    </node>

    <node pkg="turtlesim" type="turtle_teleop_key" name="turtle_teleop_key" output="screen" />
</launch>

Здесь наличие параметра/turtle_number указывает, что количество черепах равно 2.,Он будет сохранен в устройстве параметр Служить. Первый узел — это узел, на котором запущен эмулятор черепахи.,Добавьте два параметра,Представляет собой двух черепах,Одного зовут Том,Одного зовут Джерри. Затем будет импортирован параметрдокументparam.yaml. find Learning_launch представляет собой инструкцию для поиска пакетов функций.,Будет указан полный путь к пакету функций. Второй узел — это узел, который запускает клавиатуру для управления черепахой.

Создайте новую папку configdocument в пакете функций Learning_launch и создайте param.yaml.

Язык кода:javascript
копировать
cd ..
mkdir config
cd config
vim param.yaml

Содержание следующее

Язык кода:javascript
копировать
A: 123
B: "hello"

group:
        C: 456
        D: "hello"

запуск документа запуска

Язык кода:javascript
копировать
roslaunch learning_launch turtlesim_parameter_config.launch

В этот момент откроется узел симулятора черепахи, и движением черепахи можно будет управлять с помощью клавиатуры.

Теперь давайте проверим параметр параметра Служить,Открыть новый терминал,бегать

Язык кода:javascript
копировать
rosparam list

возвращаться

Язык кода:javascript
копировать
/rosdistro
/roslaunch/uris/host_guanjian_x99__37297
/rosversion
/run_id
/turtle_number
/turtlesim_node/A
/turtlesim_node/B
/turtlesim_node/background_b
/turtlesim_node/background_g
/turtlesim_node/background_r
/turtlesim_node/group/C
/turtlesim_node/group/D
/turtlesim_node/trutle_name2
/turtlesim_node/turtle_name1

Просмотр/turtle_number

Язык кода:javascript
копировать
rosparam get /turtle_number

возвращаться

Язык кода:javascript
копировать
2

Просмотр /turtlesim_node/turtle_name1

Язык кода:javascript
копировать
rosparam get /turtlesim_node/turtle_name1

возвращаться

Язык кода:javascript
копировать
Tom

Просмотр/turtlesim_node/A

Язык кода:javascript
копировать
rosparam get /turtlesim_node/A

возвращаться

Язык кода:javascript
копировать
123

Просмотр/turtlesim_node/B

Язык кода:javascript
копировать
rosparam get /turtlesim_node/B

возвращаться

Язык кода:javascript
копировать
hello

Посмотреть /turtlesim_node/group/C

Язык кода:javascript
копировать
rosparam get /turtlesim_node/group/C

возвращаться

Язык кода:javascript
копировать
456

вернуться в В папке launchdocument пакета Learning_launch создайте третий файл запуска.

Язык кода:javascript
копировать
vim start_tf_demo_c++.launch

Содержание следующее

Язык кода:javascript
копировать
<launch>
    <!-- Turlesim Node-->
    <node pkg="turtlesim" type="turtlesim_node" name="sim" />
    <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen" />

    <node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle1" name="turtle1_tf_broadcaster" />
    <node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle2" name="turtle2_tf_broadcaster" />

    <node pkg="learning_tf" type="turtle_tf_listener" name="listener" />
</launch>

Это пример предыдущего преобразования системы координат. Сначала запустите узел симулятора черепахи, затем узел управления клавиатурой симулятора черепахи, затем два вещателя под Learning_tf и, наконец, прослушиватель под Learning_tf, чтобы отслеживать взаимосвязь между двумя системами координат. Связь между черепахой 2 и командой скорости черепахи 2 выдается, чтобы позволить черепахе 2 двигаться к черепахе 1.

запуск документа запуска

Язык кода:javascript
копировать
roslaunch learning_launch start_tf_demo_c++.launch

Эффект тот же, что и раньше.

Создайте четвертый документ запуска.

Язык кода:javascript
копировать
vim start_tf_demo_py.launch

Содержание следующее

Язык кода:javascript
копировать
<launch>
    <!-- Turtlesim Node-->
    <node pkg="turtlesim" type="turtlesim_node" name="sim" />
    <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen" />

    <node name="turtle1_tf_broadcaster" pkg="learning_tf" type="turtle_tf_broadcaster.py">
        <param name="turtle" type="string" value="turtle1" />
    </node>
    <node name="turtle2_tf_broadcaster" pkg="learning_tf" type="turtle_tf_broadcaster.py">
        <param name="turtle" type="string" value="turtle2" />
    </node>

    <node pkg="learning_tf" type="turtle_tf_listener.py" name="listener" />
</launch>

вернуться вlearning_tfизscriptsпапка, изменитьодин разturtle_tf_broadcaster.py

Язык кода:javascript
копировать
cd Documents/catkin_ws/src/learning_tf/scripts
vim turtle_tf_broadcaster.py

Исправлять Содержание следующее

Язык кода:javascript
копировать
#!/home/guanjian/anaconda3/envs/py39/bin/python
# -*- coding: utf-8 -*-

import roslib
roslib.load_manifest('learning_tf')
import rospy
import tf
import turtlesim.msg

def handle_turtle_pose(msg, turtlename):
    br = tf.TransformBroadcaster()
    br.sendTransform((msg.x, msg.y, 0), tf.transformations.quaternion_from_euler(0, 0, msg.theta), rospy.Time.now(), turtlename, "world")

if __name__ == '__main__':

    rospy.init_node('turtle_tf_broadcaster')
    turtlename = rospy.get_param('~turtle')
    rospy.Subscriber('/%s/pose' % turtlename, turtlesim.msg.Pose, handle_turtle_pose, turtlename)
    rospy.spin()

запуск документа запуска

Язык кода:javascript
копировать
roslaunch learning_launch start_tf_demo_py.launch

Эффект тот же, что и раньше.

Часто используемые инструменты визуализации

инструмент qt

Запустите эмулятор черепахи и узел управления клавиатурой.

Язык кода:javascript
копировать
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
  • Инструмент просмотра журналов
Язык кода:javascript
копировать
rqt_console

Когда наша маленькая черепашка ударится о стену, инструмент rqt_console соберет логи.

Язык кода:javascript
копировать
[ WARN] [1693830491.863016173]: Oh no! I hit the wall! (Clamping from [x=5.655495, y=-0.030404])
  • инструменты рисования
Язык кода:javascript
копировать
rqt_plot

В верхней части инструмента есть опция «Тема».,После того, как мы войдём, вы сможете увидеть тему, которая сейчас находится в ROS.,В это время мы выбираем /turtle1/pose,Когда мы используем клавиатуру, она срабатывает после движения маленькой черепахи,Вы можете видеть, что в этом инструменте отображаются различные значения маленькой черепахи.,Такие как линейная скорость, угловая скорость и т. д.

  • Показать изображение с камеры
Язык кода:javascript
копировать
rqt_image_view

Этот инструмент может отображать изображения с камеры.,и карта глубины,Инфракрасные изображения и другие выходные изображения.

  • Комплексные инструменты
Язык кода:javascript
копировать
rqt

Этот инструмент может открывать все инструменты rqt, не ограничиваясь упомянутыми выше.

Интерфейс визуализации данных разработки роботов Rviz

Этот инструмент может отображать модели роботов, координаты, планирование движения, навигацию, облака точек и изображения во время разработки робота.

Rviz — это инструмент 3D-визуализации, который хорошо совместим с платформами роботов, основанными на программной платформе ROS.

  1. В rviz вы можете использовать XML для описания размера, качества, положения, материала, соединений и других атрибутов любых физических объектов, таких как роботы и окружающие объекты, и представлять их в интерфейсе.
  2. В то же время rviz может также графически отображать такую ​​информацию, как информация датчиков робота, состояние движения робота и изменения в окружающей среде в режиме реального времени.
  3. в целом,rviz использует параметры модели робота, информацию датчиков, предоставляемую роботом, и т. д. данные.,Предоставьте пользователям графическое отображение всей отслеживаемой информации. Пользователи и разработчики также могут использовать интерфейс управления rviz для,С помощью кнопок, ползунков, значений и т. д.,Управляйте поведением робота.
Язык кода:javascript
копировать
rosrun rviz rviz

Это экран, когда вы его только что открыли. Нажмите «Добавить» и выберите лидар.

Вы можете настроить имя лидара

После открытия различных функций может появиться следующий экран.

Платформа моделирования 3D-физики Gazebo

Gazebo — это платформа трехмерного физического моделирования с большими функциями.,Rviz — платформа отображения данных.,Должны быть данные для отображения,Gazebo — платформа для моделирования,Он может создавать данные без хаданных.

  1. Имеет мощный физический движок.
  2. Высококачественная отрисовка графики.
  3. Удобное программирование и графический интерфейс.
  4. Открытый исходный код и бесплатно.

Типичные сценарии применения включают в себя

  1. алгоритм тест-бота
  2. Дизайн робота
  3. Возврат в реальных сценариях

Установить

Язык кода:javascript
копировать
sudo apt-get install ros-noetic-simulators

Если это Убунту 18.04 это

Язык кода:javascript
копировать
sudo apt-get install ros-melodic-simulators

Запустить модель в

Язык кода:javascript
копировать
roslaunch gazebo_ros willowgarage_world.launch

Если это первый запуск, это займет больше времени.

После загрузки различных функций это может выглядеть так

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.