Для установки мы используем систему Ubuntu 20.04.
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main">/etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
sudo apt-get update
sudo apt install ros-noetic-desktop-full
Если это Ubuntu 18.04, вы можете использовать
sudo apt install ros-melodic-desktop-full
Установка займет много времени.
Добавьте переменные среды
sudo vim /etc/profile
Содержание следующее
source /opt/ros/noetic/setup.bash
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:~/ros_ws/src
Если это Ubuntu 18.04, то
source /opt/ros/melodic/setup.bash
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:~/ros_ws/src
осуществлять
source /etc/profile
sudo apt-get install python3-rosdep2
sudo vim /etc/hosts
Если это Ubuntu 18.04, то
source /etc/profile
sudo apt-get install python3-rosdep
sudo vim /etc/hosts
Добавить контент
199.232.28.133 raw.githubusercontent.com
осуществлять
sudo rm /etc/ros/rosdep/sources.list.d/20-default.list
sudo rosdep init
rosdep update
Если это Ubuntu 18.04, то
sudo rosdep init
rosdep update
sudo apt install python3-rosinstall python3-rosinstall-generator python3-wstool
sudo apt-get install ros-noetic-roslaunch
Если это Ubuntu 18.04, то
sudo apt install python3-catkin-pkg
sudo apt install python3-rosinstall python3-rosinstall-generator python3-wstool
sudo apt-get install ros-melodic-roslaunch
После завершения установки введите
roscore
выход
... 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]
Указывает на успешную установку
sudo apt install ros-noetic-rosbash
sudo apt install ros-noetic-catkin
sudo apt-get install ros-noetic-turtlesim
Если это Ubuntu 18.04, то
sudo apt install ros-melodic-rosbash
sudo apt install ros-melodic-catkin
sudo apt-get install ros-melodic-turtlesim
осуществлять
rosrun turtlesim turtlesim_node
Появится изображение маленькой черепахи.
осуществлять
rosrun turtlesim turtle_teleop_key
Таким образом, вы можете использовать клавиши со стрелками на клавиатуре, чтобы управлять маленькой черепахой.
Инструмент ros rqt — это серия интуитивно понятных инструментов визуализации, разработанных с использованием qt.
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, то
sudo apt-get install ros-melodic-rqt
sudo apt-get install ros-melodic-rqt-graph
sudo apt-get install ros-melodic-rqt-common-plugins
sudo apt-get install ros-noetic-cv-bridge
sudo apt-get install ros-noetic-image-transport
Если это Ubuntu 18.04, то
sudo apt-get install ros-melodic-cv-bridge
sudo apt-get install ros-melodic-image-transport
Настройте каталог jetson nano opencv (только для 18.04)
cd /opt/ros/melodic/share/cv_bridge/cmake/
sudo vim cv_bridgeConfig.cmake
Измените две строки opencv 94 и 96 на opencv4.
механизм связи
ROS — это слабосвязанная распределенная программная среда. На рисунке выше много узлов. Каждый узел представляет собой процесс, выполняющий определенную функцию в системе робота. Например, некоторые узлы выполняют распознавание изображения, а некоторые — драйвер изображения. Между ними будет промежуток. .Идет передача серии изображений. Положения между узлами не фиксированы. Например, на рисунке выше изображены два компьютера: один A и один B. Некоторые узлы могут находиться в A, а некоторые узлы могут быть в B. Они могут быть соединены посредством серии передач. методы завершения общения. Язык программирования каждого узла не фиксирован. Вы можете использовать Python или C++.
На рисунке выше есть три узла: узел камеры, узел обработки изображения и узел отображения изображения.
Существует два основных метода связи между узлами — темы и сервисы.
тема
Служить
темаи Служить Разница
| тема | Служить |
---|---|---|
синхронность | асинхронный | синхронный |
модель связи | публиковать/подписаться | Служить исполнителю/заказчику |
базовый протокол | ROSTCP/ROSUDP | ROSTCP/ROSUDP |
механизм обратной связи | никто | иметь |
буфер | иметь | никто |
в реальном времени | слабый | мощный |
Отношения узлов | многие ко многим | Один ко многим (один сервер) |
Применимые сценарии | передача данных | логическая обработка |
параметр
это в РОС Мастер поддерживает сервер параметр Служить, и ко всем узлам можно получить доступ через сеть.
файловая система
Базовая единица программного обеспечения ROS, включая исходный код узла, файлы конфигурации, определения данных и т. д.
Запишите основную информацию о пакете функций, включая информацию об авторе, информацию о лицензии, параметры зависимостей, флаги компиляции и т. д.
Организуйте несколько пакетов функций, которые служат одной и той же цели.
Запустить ROS Master
roscore
Запустить узел
rosrun turtlesim turtlesim_node
Rosrun обычно означает два параметра,Первый параметрturtlesim — это имя пакета функций.,Второй параметрturtlesim_node — это узел,это узел эмулятора,Это маленькая черепаха, которую я видел раньше.
Запустить другой узел
rosrun turtlesim turtle_teleop_key
Этот узел представляет собой узел, который управляет движением маленькой черепахи с помощью клавиш вверх, вниз, влево и вправо на клавиатуре.
rqt_graph
Это инструмент, отображающий расчетные схемы систем.,Ядром механизма связи ROS является вычислительный граф.,С помощью схемы можно быстро понять общую картину всей системы.
В этом интерфейсе перечислены узлы текущей системы (эллиптическая часть).,Вот 2 узла,Узел симулятора маленькой черепахи Turtlesim,Узел управления клавиатурой teleop_turtle. Между двумя узлами осуществляется передача данных.,Среди них есть тема/turtle1/cmd_vel,Специально используется для общения.
rosnode
Вернусь в это время и значение параметра и параметра, стоящего за ним
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'
В это время мы используем
rosnode list
Узел, который будет осуществлять деятельность
/rosout
/teleop_turtle
/turtlesim
Последние два узла v — это эмулятор маленькой черепахи и контроллер клавиатуры, который мы начали.,А /rosout — это тема ROS по умолчанию.,Он собирает информацию журнала всех узлов и передает ее в последующий интерфейс для отображения.,В общем, не стоит волноваться.
Просмотр конкретной информации об узле
rosnode info /turtlesim
Вернусь в это время
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 представляет данные, отправленные с помощью команды клавиатуры, и управляет движением маленькой черепахи с помощью данных, на которые она подписана. Службы Служить выпускаются этим узлом, а некоторые конфигурации выполняются через Служить в. Внизу указаны идентификационные номера и нижний слой механизма. связи。
rostopic
Вернусь в это время и значение параметра и параметра, стоящего за ним
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'
Посмотреть текущий список имеющихся тем в системе
rostopic list
Вернуться в это время
/rosout
/rosout_agg
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
в/turtle1/cmd_vel — это тема, которая выдает инструкции управления для маленькой черепахи. Узел управления клавиатурой и узел управления маленькой черепахой взаимодействуют через эту тему.
Отдавайте команды для перемещения черепах
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 будет выполнена только один раз. Чтобы черепаха продолжала двигаться, ей необходимо задать цикл.
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 раз в секунду.
Просмотр содержимого структуры данных сообщения
rosmsg show geometry_msgs/Twist
Здесь рассматривается структура данных geome_msgs/Twist, возвращаемая
geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z
rosservice
Вернусь в это время и значение параметра и параметра, стоящего за ним
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'
Просмотреть все текущие
rosservice list
возвращаться
/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.
породить новую черепаху
rosservice call /spawn "x: 2.0
y: 2.0
theta: 0.0
name: 'turtle2'"
rosbag record -a -O cmd_record
Запись здесь означает запись,-a — сохранить все записи,-O означает сохранение данных в сжатый пакет.,cmd_record — сохраненное имя
возвращаться
[ 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 Узел эмулятора Мастера и маленькой черепахи.
rosbag play cmd_record.bag
Таким образом, мы видим, что путь, пройденный маленькой черепахой, такой же, как и записанный.
набор команд
cd Documents/
mkdir -p catkin_ws/src
cd catkin_ws/src/
catkin_init_workspace
В настоящее время в рабочей области нет кода, но его все равно можно использовать.
cd ..
catkin_make install
В это время будут созданы еще три папки — build, devel, install.
source devel/setup.bash
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
CMakeLists.txt include package.xml src
Среди них include и src — это папки, include — для размещения заголовочных файлов C++, а src — для размещения кода .cpp.
Вернитесь в папку catkin_ws.
cd ..
catkin_make
source devel/setup.bash
echo $ROS_PACKAGE_PATH
Вернуться в это время
/home/user/Documents/catkin_ws/src:/opt/ros/noetic/share
Он указывает место, где ROS может найти наш пакет функций (пользователь — это ваше собственное имя пользователя).
В test_pkg будет два важных элемента — CMakeLists.txt и package.xml. Давайте посмотрим на содержимое package.xml.
<?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
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。
реализация на С++
Войти в рабочую область
cd Documents/catkin_ws/src
Создайте новый пакет функций темы.
catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim
Введите каталог src пакета функций.
cd learning_topic/src
Создайте нужные нам файлы C++.
vim velocity_publisher.cpp
Содержание следующее
/*
* Эта программа опубликует черепаху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.
cd ..
vim CMakelists.txt
добавить в Содержание следующее
add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})
Вернитесь в папку catkin_ws.,начинатькомпилировать
cd ../..
catkin_make
Установите переменные среды после завершения компиляции
source devel/setup.bash
Если мы не хотим устанавливать переменные среды каждый раз после компиляции, мы можем напрямую изменить /etc/profile.
sudo vim /etc/profile
Добавить контент
source /home/user/Documents/catkin_ws/devel/setup.bash
Измените пользователя на свое собственное имя пользователя
source /etc/profile
изучить Программа, в другом окне терминала изучить
roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic velocity_publisher
Таким образом, мы можем увидеть, как маленькая черепаха движется по кругу.
Реализация Python
Перейдите в папку пакета
cd Documents/catkin_ws/src/learning_topic
Создайте новую папку скриптов
mkdir scripts
cd scripts
Создайте нужные нам файлы Python
vim velocity_publisher.py
Содержание следующее
#!/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
Установить разрешения
chmod 777 velocity_publisher.py
Здесь нам понадобится операционная среда Python,Подробную информацию см.乌班图УстановитьPytorch、Tensorflow Среда КудавУстановить Anaconda。
Установите два необходимых пакета
conda activate py39
pip install pyyaml
pip install rospkg
осуществлять Заказ(разные окна терминала)
roscore
rosrun turtlesim turtlesim_node
rosrun learning_topic velocity_publisher.py
Это будет иметь тот же эффект, что и использование C++ ранее.
реализация на С++
Введите пакет функций Learning_topic
cd Documents/catkin_ws/src/learning_topic/src
Создайте нужные нам файлы C++.
vim pose_subscriber.cpp
Содержание следующее
/*
* Эта процедура подпишется на /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.
cd ..
vim CMakelists.txt
добавить в Содержание следующее
add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})
Вернитесь в папку catkin_ws и начните компилировать.
cd ../..
catkin_make
изучить Программа, в другом окне терминала изучить
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
rosrun learning_topic pose_subscriber
В этот момент мы увидим,Используем клавиатуру, чтобы переместить черепаху,Координаты черепашки будут отображаться вpose_subscriber в режиме реального времени.
[ 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.
cd Documents/catkin_ws/src/learning_topic/scripts
vim pose_subscriber.py
Содержание следующее
#!/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()
Установить разрешения
chmod 777 pose_subscriber.py
осуществлять Заказ (разные окна терминала)
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
rosrun learning_topic pose_subscriber.py
Войти в рабочую область
cd Documents/catkin_ws/src
Создать новый пакет функций
catkin_create_pkg learning_transfer_img sensor_msgs cv_bridge roscpp std_msgs image_transport
Введите каталог src пакета функций.
cd learning_transfer_img/src
Создайте файл C++ издателя.
vim img_publisher.cpp
Содержание следующее
#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++ для создания подписчика
vim img_subscriber.cpp
Содержание следующее
#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.
cd ..
vim CMakelists.txt
добавить в Содержание следующее
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 и начните компилировать.
cd ../..
catkin_make
изучить Программа, в другом окне терминала изучить
roscore
rosrun learning_transfer_img img_subscriber
rosrun learning_transfer_img img_publisher
реализация на С++
Перейдите в папку пакета
cd Documents/catkin_ws/src/learning_topic
Создать новую папку сообщений
mkdir msg
cd msg
Создадим нужные нам файлы сообщений
vim Person.msg
Содержание следующее
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 femal = 2
Здесь мы создаем информацию о человеке. Это зависит от языка, и ROS будет преобразована в программу C++ или Python в соответствии с определением.
Установить правила компиляции
Вернитесь в папку Learning_topic, измените package.xml и добавьте зависимости пакета функций динамически создаваемой программы.
cd ..
vim package.xml
добавить виз Содержание следующее
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
в<build_depend>длякомпилироватьполагаться,<exec_depend>дляосуществлятьполагаться。
Изменить CMakeLists.txt
vim CMakeLists.txt
Содержание следующее
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 и начните компилировать.
cd ../..
catkin_make
В это время мы увидим дополнительные документы Person.h в разделе Documents/catkin_ws/devel/include/learning_topicОглавление.,Он автоматически генерируется компилятором ROS.,Содержание следующее
// 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.
cd Documents/catkin_ws/src/learning_topic/src
Создать издателя
vim person_publisher.cpp
Содержание следующее
/*
* Эта процедура опубликует /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;
}
Создать подписчика
vim person_subscriber.cpp
Содержание следующее
/*
* Эта процедура подпишется на /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
cd ..
vim CMakelists.txt
добавить в Содержание следующее
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 и начните компилировать.
cd ../..
catkin_make
изучить Программа, в другом окне терминала изучить
roscore
rosrun learning_topic person_subscriber
rosrun learning_topic person_publisher
Таким образом, на стороне издательства всегда будут публиковаться новости персонала.
[ 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
И абонент начнет получать сообщения от людей.
[ 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
Перейдите в папку сценариев пакета.
cd Documents/catkin_ws/src/learning_topic/scripts
Создать издателя
vim person_publisher.py
Содержание следующее
#!/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
Создать подписчика
vim person_subscriber.py
Содержание следующее
#!/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()
Дайте им разрешение
chmod 777 person_publisher.py
chmod 777 person_subscriber.py
изучить Программа, в другом окне терминала изучить
roscore
rosrun learning_topic person_subscriber.py
rosrun learning_topic person_publisher.py
реализация на С++
Войти в рабочую область
cd Documents/catkin_ws/src
Создать новый пакет функций «Служить»
catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim
Введите каталог src пакета функций.
cd learning_service/src
Создайте нужные нам файлы C++.
vim turtle_spawn.cpp
Содержание следующее
/*
* Эта процедура запросит /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。
cd ..
vim CMakelists.txt
добавить в Содержание следующее
add_executable(turtle_spawn src/turtle_spawn.cpp)
target_link_libraries(turtle_spawn ${catkin_LIBRARIES})
Вернитесь в папку catkin_ws и начните компилировать.
cd ../..
catkin_make
изучить Программа, в другом окне терминала изучить
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_spawn
На этом этапе мы уже можем видеть вторую черепаху, появившуюся в окне эмулятора черепахи. и распечатать журнал
[ 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.
[ INFO] [1692399646.697808644]: Spawning turtle [turtle2] at x=[2.000000], y=[2.000000], theta=[0.000000]
Реализация Python
Перейдите в папку пакета
cd Documents/catkin_ws/src/learning_service
Создайте новую папку скриптов
mkdir scripts
cd scripts
Создадим то, что нам нужно Python документ
vim turtle_spawn.py
Содержание следующее
#!/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()))
Дайте ему разрешение на изучение
chmod 777 turtle_spawn.py
изучить Программа, в другом окне терминала изучить
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_spawn.py
реализация на С++
Введите пакет функций Learning_service
cd Documents/catkin_ws/src/learning_service/src
Создайте нужные нам файлы C++.
vim turtle_command_server.cpp
Содержание следующее
/*
* Эта процедура будетосуществлять/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。
cd ..
vim CMakelists.txt
добавить в Содержание следующее
add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})
Вернитесь в папку catkin_ws и начните компилировать.
cd ../..
catkin_make
изучить Программа, в другом окне терминала изучить
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_command_server
rosservice call /turtle_command "{}"
После завершения изучения мы увидели, что маленькая черепаха постоянно двигалась кругами.
Когда мы отправим запрос еще раз
rosservice call /turtle_command "{}"
Детеныш черепахи перестанет двигаться.
Терминал Turtle_command_server Служить напечатает два таких журнала.
[ INFO] [1692495991.674337329]: Publish turtle velocity command [Yes]
[ INFO] [1692496732.674292008]: Publish turtle velocity command [No]
Здесь «Да» означает, что черепаха начинает двигаться, а «Нет» означает, что черепаха перестает двигаться.
Реализация Python
Перейдите в папку сценариев пакета.
cd Documents/catkin_ws/src/learning_service/scripts
Создадим то, что нам нужно Python документ
vim turtle_command_server.py
Содержание следующее
#!/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()
Предоставить разрешения на изучение
chmod 777 turtle_command_server.py
изучить Программа, в другом окне терминала изучить
roscore
rosrun turtlesim turtlesim_node
rosrun learning_service turtle_command_server.py
rosservice call /turtle_command "{}"
сноваосуществлять
rosservice call /turtle_command "{}"
В это время в конце Служить будет напечатано всего
[INFO] [1692498798.819324]: Publish trutle velocity command![1]
[INFO] [1692498830.254050]: Publish trutle velocity command![0]
реализация на С++
Перейдите в папку пакета
cd Documents/catkin_ws/src/learning_service
Новыйданныедокументпапка
mkdir srv
cd srv
Создадим то, что нам нужноданныедокумент
vim Person.srv
Содержание следующее
string name
uint8 age
uint8 sex
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
---
string result
Отличие от сообщения темы заключается в том, что документ данных содержит части запроса и ответа, разделенные --- посередине.
Установить правила компиляции
возвращаться learning_service папка, изменить package.xml, добавляет функциональные зависимости пакетов для динамически генерируемых программ.
cd ..
vim package.xml
добавить виз Содержание следующее
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
в <build_depend> длякомпилироватьполагаться,<exec_depend > дляосуществлятьполагаться。
Изменить CMakeLists.txt
vim CMakeLists.txt
Содержание следующее
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 и начните компилировать.
cd ../..
catkin_make
В это время мы увидим еще три документа в разделе Documents/catkin_ws/devel/include/learning_serviceОглавление. Person.h , PersonRequest.h, PersonResponse.h, которые состоят из ROS Компилируется автоматически, нам нужно только использовать заголовочный документ Person.h при его использовании. Person.hСодержание следующее
// 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Содержание следующее
// 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Содержание следующее
// 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 исходный коддокументпапка
cd Documents/catkin_ws/src/learning_service/src
создавать Служитьконец
vim person_server.cpp
Содержание следующее
/*
* Эта процедура будетосуществлять/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;
}
Создать клиента
vim person_client.cpp
Содержание следующее
/*
* Эта процедура запросит /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
cd ..
vim CMakelists.txt
добавить в Содержание следующее
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 и начните компилировать.
cd ../..
catkin_make
изучить Программа, в другом окне терминала изучить
roscore
rosrun learning_service person_client
rosrun learning_service person_server
изучить Завершить в клиентевозвращаться
[ 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
Распечатать журналы на стороне Служить
[ INFO] [1692650916.045710322]: Ready to show person informtion
[ INFO] [1692650916.055297356]: Person: name:Tom age:20 sex:1
Реализация Python
Перейдите в папку сценариев пакета.
cd Documents/catkin_ws/src/learning_service/scripts
создавать Служитьконец
vim person_server.py
Содержание следующее
#!/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()
Создать клиента
vim person_client.py
Содержание следующее
#!/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()))
Дайте им разрешение
chmod 777 person_server.py
chmod 777 person_client.py
изучить Программа, в другом окне терминала изучить
roscore
rosrun learning_service person_client.py
rosrun learning_service person_server.py
в РОС Мастер среднего размера с одним параметром. Утилита — Параметр. Сервер — глобальный словарь, используемый для сохранения конфигурации каждого узла. На картинке выше робот сохраняет три значения — имя робота, радиус и высоту. Эти параметры доступны глобально для всех узлов. Например, в узле Если А хочет запросить имя робота, оно будет отправлено в ROS. Мастер отправляет запрос и получает результат от my_robot. Таким образом можно обработать все узлы.
параметр Служитьустройство Использование
Сначала запустите ROS Master и узел эмулятора маленькой черепахи.
roscore
rosrun turtlesim turtlesim_node
вход
rosparam
возвращаться
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
Указывает, что команда, имеющая этот параметр, может быть установлена.
Запросить, сколько узлов параметров имеется
rosparam list
возвращаться
/rosdistro
/roslaunch/uris/host_guanjian_x99__40731
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r
в
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r
Представляет цвет фона симулятора черепахи.
/rosdistro
/roslaunch/uris/host_guanjian_x99__40731
/rosversion
/run_id
для РОС Мастер сам предлагает параметр,可以поставлятьROSизномер версии,Идентификатор запущенного процесса.
Получите значение B в RGB цвета фона эмулятора маленькой черепахи.
rosparam get /turtlesim/background_b
возвращаться
255
Получите значение G в RGB цвета фона эмулятора маленькой черепахи.
rosparam get /turtlesim/background_g
возвращаться
86
Получите значение R в цвете фона RGB эмулятора маленькой черепахи.
rosparam get /turtlesim/background_r
возвращаться
69
Получить дистрибутив ROS
rosparam get /rosdistro
возвращаться
'noetic
'
Получить номер версии ROS
rosparam get /rosversion
возвращаться
'1.16.0
'
Измените значение B цвета фона RGB эмулятора маленькой черепахи.
rosparam set /turtlesim/background_b 100
Здесь нам нужно обратить внимание на,Хотя мы изменили цвет фона,Но это вступит в силу не сразу.,Нам нужно отправить запрос на Служить, чтобы узел эмулятора черепахи перечитал параметр.
rosservice call /clear "{}"
В это время меняется цвет фона эмулятора маленькой черепахи.
ВоляparameterSluzhitkeiwareпараметр сохранить как документ
rosparam dump param.yaml
После сохранениядокументиз Содержание следующее
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.
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
загрузить
rosparam load param.yaml
Отправить запрос Служить еще раз
rosservice call /clear "{}"
На этом этапе мы видим, что цвет фона эмулятора маленькой черепахи изменился на черный.
Удаляем определенный параметр, например удаляем background_g
rosparam delete /turtlesim/background_g
На этом этапе мы читаем список параметров
rosparam list
возвращаться
/rosdistro
/roslaunch/uris/host_guanjian_x99__40731
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_r
Отправить запрос Служить еще раз
rosservice call /clear "{}"
Цвет фона эмулятора черепахи также изменится соответствующим образом.
Войти в рабочую область
cd Documents/catkin_ws/src
Создать новый пакет
catkin_create_pkg learning_parameter roscpp rospy std_srvs
В пакете функций Входитьlearning_parameter
cd learning_parameter/src
Создайте нужные нам файлы C++.
vim parameter_config.cpp
Содержание следующее
/*
* Эта процедура устанавливает/считывает параметр в процедуре маленькой черепахи.
*/
#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。
cd ..
vim CMakelists.txt
добавить в Содержание следующее
add_executable(parameter_config src/parameter_config.cpp)
target_link_libraries(parameter_config ${catkin_LIBRARIES})
Вернитесь в папку catkin_ws и начните компилировать.
cd ../..
catkin_make
изучить Программа, в другом окне терминала изучить
roscore
rosrun turtlesim turtlesim_node
rosrun learning_parameter parameter_config
возвращаться
[ 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]
И цвет фона окна эмулятора черепахи изменится на белый.
Перейдите в папку пакета,并создавать脚本документпапка,Входить Должендокументпапка
cd Documents/catkin_ws/src/learning_parameter
mkdir scripts
cd scripts
Создадим то, что нам нужно Python документ
vim parameter_config.py
Содержание следующее
#!/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()
Предоставить разрешения на изучение
chmod 777 parameter_config.py
изучить Программа, в другом окне терминала изучить
roscore
rosrun turtlesim turtlesim_node
rosrun learning_parameter parameter_config.py
Преобразование координат положения робота представляет собой серию матричных операций 4*4.,Подробную информацию см.Подбор баллов знаний SLAMвЖесткое движение тела。
Преобразование координат TF
TF — это инструмент в ROS, который обеспечивает операции преобразования координат робота.
Как достичь
Это не та тема Тема и Служить Сервис, о которой мы говорили ранее. После запуска 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. Метод трансформации заключается в следующем.
Пример преобразования координат
Установите компонент преобразования координат черепахи.
sudo apt-get install ros-noetic-turtle-tf
Если это Убунту Система 18.04
sudo apt-get install ros-melodic-turtle-tf
Замените нашу среду conda. Эта среда должна соответствовать нашей предыдущей среде программирования Python и установить numpy.
conda activate py39
pip install numpy
запустить сценарий,Это документ-скрипт,Вы можете запустить много узлов одновременно
roslaunch turtle_tf turtle_tf_demo.launch
После завершения запуска,Мы увидим окно с двумя черепашками.,И сделать так, чтобы одна черепашка подошла к другой черепахе.
Запустите узел управления кнопкой маленькой черепахи.
rosrun turtlesim turtle_teleop_key
В это время мы с помощью клавиатуры перемещаем маленькую черепаху, а другая маленькая черепаха последует за ней.
Чтобы отслеживать информацию маленькой черепахи, откройте новый терминал, а также необходимо переключить среду конды.
conda activate py39
rosrun tf view_frames
После запуска он сообщит
TypeError: cannot use a string pattern on a bytes-like object
Это связано с тем, что в исходном коде функционального документа используется Python 2, а в нашей среде — Python 3. Поэтому нам нужно изменить
sudo vim /opt/ros/noetic/lib/tf/view_frames
Измененный контент
vstr = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[1]
vstr = str(vstr)
в то же время Исправлятьдокументпапка和view_framesМестоиметь ВОЗ
sudo chown user:user /opt/ros/noetic/lib/tf
sudo chown user:user /opt/ros/noetic/lib/tf/view_frames
Повторный запуск
rosrun tf view_frames
Два новых документа будут созданы в папке /opt/ros/noetic/lib/tf.
frames.gv
frames.pdf
Здесь мы в основном рассматриваем документ framework.pdf.
Это означает, что в текущем симуляторе есть три системы координат.,Один - мир,Это глобальная система координат,Он представляет собой начало координат всего симулятора. Эта координатная точка никогда не будет перемещаться. Две другие системы координат,Одного зовут черепаха1,Один называется tutle2,Они расположены на двух черепашках. Turtle1 и Tutle2 продолжат перекрываться.,Но по сравнению с миром он постоянно меняется.
rosrun tf tf_echo turtle1 turtle2
Черепаха1 и черепаха2 здесь представляют две системы координат.
В это время, когда мы используем клавиатуру для управления движением маленькой черепахи, инструмент записывает преобразование между двумя системами координат.
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。
rosrun rviz rviz -d `rospack find turtle_tf`/rviz/turtle_rviz.rviz
После открытия вам нужно изменить «Фиксированный кадр» на «Мир», затем нажать кнопку «Добавить», чтобы добавить опцию TF. В это время, если мы будем использовать клавиатуру для управления движением маленькой черепахи, мы увидим, что система координат черепахи2 в инструменте rviz постоянно перемещается в систему координат черепахи1.
Начало координат в середине сетки,Это начало мировых координат,С левой стороны есть две точки: красная и зеленая.,Это две системы координат черепаха1 и черепаха2.
Программная реализация трансляции и мониторинга системы координат ТФ
Войти в рабочую область
cd Documents/catkin_ws/src
Создать новый пакет функций
catkin_create_pkg learning_tf roscpp rospy tf turtlesim
Введите каталог src пакета функций.
cd learning_tf/src
Создадим то, что нам нужно广播устройствоC++документ
vim turtle_tf_broadcaster.cpp
Содержание следующее
/*
* Эта процедура генерирует 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++документ
vim turtle_tf_listener.cpp
Содержание следующее
/*
* Эта процедура отслеживает 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。
cd ..
vim CMakelists.txt
добавить в Содержание следующее
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 и начните компилировать.
cd ../..
catkin_make
изучить Программа, в другом окне терминала изучить
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
Управляя клавиатурой и перемещая первую черепашку, мы обнаружим, что вторая черепашка следует за ней.
Перейдите в папку пакета
cd Documents/catkin_ws/src/learning_tf
Создайте новую папку скриптов
mkdir scripts
cd scripts
Создадим то, что нам нужен вещатель Python документ
vim turtle_tf_broadcaster.py
Содержание следующее
#!/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документ
vim turtle_tf_listener.py
Содержание следующее
#!/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()
Установить разрешения
chmod 777 turtle_tf_broadcaster.py
chmod 777 turtle_tf_listener.py
осуществлять Заказ (разные окна терминала)
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)
<launch>
<node pkg="turtlesim" name="sim1" type="turtlesim_node" />
<node pkg="turtlesim" name="sim2" type="turtlesim_node" />
</launch>
этотв<launch>является корневым узлом。
âПервые три атрибута являются наиболее основными атрибутами, а следующие атрибуты являются необязательными.
<param name="output_frame" value="odom" />
<rosparam file="params.yaml" command="load" ns="params" />
<arg name="arg-name" default="arg-value" />
вызов
<param name="foo" value="$(arg arg-name)" />
<node name="node" pkg="package" type="type" args="$(arg arg-name)" />
Оба вызова здесь являются одним и тем же аргументом вызова. Они не имеют ничего общего друг с другом.
<remap from="/turtlebot/cmd_vel" to="/cmd_vel" />
Здесь следует отметить, что при переназначении,Тогда исходное имя больше не существует,Только имя после отображения.
<include file="$(dirname)/other.launch" />
файл: включены другие пути к запускаемым документам
Больше тегов можно найтиhttps://wiki.ros.org/roslaunch/XML
действовать
Войти в рабочую область
cd Documents/catkin_ws/src
Создать новый пакет функций, здесь нам не нужны никакие зависимости
catkin_create_pkg learning_launch
Войдите в пакет функций и создайте папку запуска документов.
cd learning_launch
mkdir launch
cd launch
Создадим то, что нам нужнопервыйlaunchдокумент
vim simple.launch
Содержание следующее
<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 и начните компилировать.
cd ../../..
catkin_make
запуск документа запуска
roslaunch learning_launch simple.launch
бревновыход
... 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, создав второй файл запуска
cd src/learning_launch/launch
vim turtlesim_parameter_config.launch
Содержание следующее
<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.
cd ..
mkdir config
cd config
vim param.yaml
Содержание следующее
A: 123
B: "hello"
group:
C: 456
D: "hello"
запуск документа запуска
roslaunch learning_launch turtlesim_parameter_config.launch
В этот момент откроется узел симулятора черепахи, и движением черепахи можно будет управлять с помощью клавиатуры.
Теперь давайте проверим параметр параметра Служить,Открыть новый терминал,бегать
rosparam list
возвращаться
/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
rosparam get /turtle_number
возвращаться
2
Просмотр /turtlesim_node/turtle_name1
rosparam get /turtlesim_node/turtle_name1
возвращаться
Tom
Просмотр/turtlesim_node/A
rosparam get /turtlesim_node/A
возвращаться
123
Просмотр/turtlesim_node/B
rosparam get /turtlesim_node/B
возвращаться
hello
Посмотреть /turtlesim_node/group/C
rosparam get /turtlesim_node/group/C
возвращаться
456
вернуться в В папке launchdocument пакета Learning_launch создайте третий файл запуска.
vim start_tf_demo_c++.launch
Содержание следующее
<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.
запуск документа запуска
roslaunch learning_launch start_tf_demo_c++.launch
Эффект тот же, что и раньше.
Создайте четвертый документ запуска.
vim start_tf_demo_py.launch
Содержание следующее
<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
cd Documents/catkin_ws/src/learning_tf/scripts
vim turtle_tf_broadcaster.py
Исправлять Содержание следующее
#!/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()
запуск документа запуска
roslaunch learning_launch start_tf_demo_py.launch
Эффект тот же, что и раньше.
инструмент qt
Запустите эмулятор черепахи и узел управления клавиатурой.
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
rqt_console
Когда наша маленькая черепашка ударится о стену, инструмент rqt_console соберет логи.
[ WARN] [1693830491.863016173]: Oh no! I hit the wall! (Clamping from [x=5.655495, y=-0.030404])
rqt_plot
В верхней части инструмента есть опция «Тема».,После того, как мы войдём, вы сможете увидеть тему, которая сейчас находится в ROS.,В это время мы выбираем /turtle1/pose,Когда мы используем клавиатуру, она срабатывает после движения маленькой черепахи,Вы можете видеть, что в этом инструменте отображаются различные значения маленькой черепахи.,Такие как линейная скорость, угловая скорость и т. д.
rqt_image_view
Этот инструмент может отображать изображения с камеры.,и карта глубины,Инфракрасные изображения и другие выходные изображения.
rqt
Этот инструмент может открывать все инструменты rqt, не ограничиваясь упомянутыми выше.
Интерфейс визуализации данных разработки роботов Rviz
Этот инструмент может отображать модели роботов, координаты, планирование движения, навигацию, облака точек и изображения во время разработки робота.
Rviz — это инструмент 3D-визуализации, который хорошо совместим с платформами роботов, основанными на программной платформе ROS.
rosrun rviz rviz
Это экран, когда вы его только что открыли. Нажмите «Добавить» и выберите лидар.
Вы можете настроить имя лидара
После открытия различных функций может появиться следующий экран.
Платформа моделирования 3D-физики Gazebo
Gazebo — это платформа трехмерного физического моделирования с большими функциями.,Rviz — платформа отображения данных.,Должны быть данные для отображения,Gazebo — платформа для моделирования,Он может создавать данные без хаданных.
Типичные сценарии применения включают в себя
Установить
sudo apt-get install ros-noetic-simulators
Если это Убунту 18.04 это
sudo apt-get install ros-melodic-simulators
Запустить модель в
roslaunch gazebo_ros willowgarage_world.launch
Если это первый запуск, это займет больше времени.
После загрузки различных функций это может выглядеть так