Introduction to ROS of Jetson nano--ROS integrated development and ROS communication study notes


1. ROS integrated development environment construction

insert image description here

VSCode, the full name of Visual Studio Code, is a lightweight code editor from Microsoft, which is free, open source and powerful. It supports syntax highlighting, smart code completion, custom hotkeys, bracket matching, code snippets, code comparison Diff, GIT and other features of almost all mainstream programming languages, supports plug-in extensions, and is designed for web development and cloud application development. Optimized.

vscode download https://code.visualstudio.com/docs?start=true

cd to the deb installation package directory of vscode

sudo dpkg -i xxxx.deb

Open vscode after installation, you need to download some plug-ins, such as Python extension, C/C++ extension, ROS plug-in, Simplified Chinese plug-in, CMake plug-in, etc. After downloading, create a workspace and create a src file package under the workspace

sudo mkdir -p /home/nvidia/xxx/src
cd /home/nvidia/xxx

Add permissions to the workspace and src file package just created

sudo chmod +777 /home/nvidia/xxx 
sudo chmod +777 /home/nvidia/xxx/src

Then execute the catkin_make compilation command in the workspace directory

catkin_make

Among them, CMake is a generator for the make tool, which is a higher-level tool. It simplifies the compilation and construction process, can manage large projects, and has good scalability. For a large-scale platform such as ROS, CMake is used, and ROS extends CMake, so there is a Catkin compilation system. Below is the file structure of the entire ROS workspace.
insert image description here

WorkSpace --- 自定义的工作空间

    |--- build:编译空间,用于存放CMake和catkin的缓存信息、配置信息和其他中间文件。

    |--- devel:开发空间,用于存放编译后生成的目标文件,包括头文件、动态&静态链接库、可执行文件等。

    |--- src: 源码

        |-- package:功能包(ROS基本单元)包含多个节点、库与配置文件,包名所有字母小写,只能由字母、数字与下划线组成

            |-- CMakeLists.txt 配置编译规则,比如源文件、依赖项、目标文件

            |-- package.xml 包信息,比如:包名、版本、作者、依赖项...(以前版本是 manifest.xml)

            |-- scripts 存储python文件

            |-- src 存储C++源文件

            |-- include 头文件

            |-- msg 消息通信格式文件

            |-- srv 服务通信格式文件

            |-- action 动作格式文件

            |-- launch 可一次性运行多个节点 

            |-- config 配置信息

        |-- CMakeLists.txt: 编译的基本配置

Execute the terminal command in the workspace to open vscode

code .

2. ROS communication mechanism and commands

insert image description here

The communication mechanism of ROS basically relies on the RPC protocol framework,RPC (Remote Procedure Call Protocol) is a protocol that requests services from remote computer programs over the network without requiring knowledge of the underlying network technology, the calling process is mainly divided into several steps:

1. The service consumer (client) calls the service locally;
2. After receiving the call, the client stub is responsible for assembling methods, parameters, etc. into a message body that can be transmitted over the network;
3. The client stub finds the service address and sends The message is sent to the server;
4. The server stub decodes the message after receiving the message;
5. The server stub calls the local service according to the decoding result;
6. The local service executes and returns the result to the server stub;
7. The server stub packs the returned result 8. The client stub receives
the message and decodes it;
9. The service consumer gets the final result.

insert image description here

The ROS communication layer is part of the ros_comm stack and follows the publish/subscribe model. In topic communication, a node can publish some topics, and other nodes can subscribe to this topic; the mechanism of services is similar. Topics and services are designed as a fixed type, and published after ROS packaging.

1. Topic communication

The implementation model of topic communication is relatively easy to understand, and its process is similar to the communication method of MQTT. There are three roles involved in this model:

ROS Master (manager)

Talker (Publisher)

Listener (subscriber)

First, the client needs to register information with the ROS Master. The registration information includes the topic, the data type of the message, the size of the message queue, etc. The ROS Master is responsible for keeping the information registered by the Talker and Listener, and matching the Talker and Listener with the same topic to help the Talker Establish a connection with the Listener. After the connection is established, the Talker can publish messages, and the published messages will be subscribed by the Listener

insert image description here

2. Service communication

Service communication is similar to topic communication, and this model also involves three roles:

ROS master (manager)

Server (server)

Client (client)

ROS Master is responsible for keeping the registration information of Server and Client, and matching Server and Client with the same topic, helping Server and Client establish a connection. After the connection is established, Client sends request information, and Server returns response information.

insert image description here

After the Client is started, it will also register its own information in the ROS Master through RPC, including the name of the service that needs to be requested. ROS Master will add the registration information of the node to the registry. ROS Master will match the Server and Client according to the information in the registry, and send the Server's TCP address information to the Client through RPC. Client uses TCP to establish a network connection with Server according to the response information in step 2, and sends request data. The Server receives and parses the requested data, and generates a response result and returns it to the Client.

3. Parameter service

The parameter server implementation is the simplest, and there are three main actors involved in this model:

ROS Master (manager)

Talker (parameter setter)

Listener (parameter caller)

ROS Master stores parameters as a public container, Talker can set parameters in the container, and Listener can get parameters.

insert image description here
Talker sends parameters (including parameter name and parameter value) to the parameter server through RPC, and ROS Master saves the parameters in the parameter list. The Listener sends a parameter search request to the parameter server through RPC, and the request includes the name of the parameter to be searched. ROS Master finds the parameter value according to the parameter name provided in the request in step 2, and sends the query result to the Listener through RPC.

4. ROS common commands

rosnode

rosnode ping    测试到节点的连接状态
rosnode list    列出活动节点
rosnode info    打印节点信息
rosnode machine    列出指定设备上节点
rosnode kill    杀死某个节点
rosnode cleanup    清除不可连接的节点

rosy

rostopic bw     显示主题使用的带宽
rostopic delay  显示带有 header 的主题延迟
rostopic echo   打印消息到屏幕
rostopic find   根据类型查找主题
rostopic hz     显示主题的发布频率
rostopic info   显示主题相关信息
rostopic list   显示所有活动状态下的主题
rostopic pub    将数据发布到主题
rostopic type   打印主题类型

rosmsg

rosmsg show    显示消息描述
rosmsg info    显示消息信息
rosmsg list    列出所有消息
rosmsg md5    显示 md5 加密后的消息
rosmsg package    显示某个功能包下的所有消息
rosmsg packages    列出包含消息的功能包

rosservice

rosservice args 打印服务参数
rosservice call    使用提供的参数调用服务
rosservice find    按照服务类型查找服务
rosservice info    打印有关服务的信息
rosservice list    列出所有活动的服务
rosservice type    打印服务类型
rosservice uri    打印服务的 ROSRPC uri

3. Python implements ROS communication - - control and read the status of the little turtle

Switch to the vscode interface, first right-click under the workspacesrc folder, select the Create Catkin Package option, give the new folder a name, and add the following dependent packages

roscpp rospy std_msgs

The src folder under the new folder directory is used to store c++ files, and a scripts folder is created to store python files

1. Configure the package.xml file

First configure the package.xml file, which mainly declares the package name that compilation and execution depend on. Here you can add it according to your own needs. For example, if you customize a message file, you need to add compilation dependencies and runtime dependencies <build_depend>message_generation</build_depend>.<exec_depend>message_runtime</exec_depend>

<?xml version="1.0"?>
<!-- 格式: 以前是 1,推荐使用格式 2 -->
<package format="2">
  <!-- 包名 -->
  <name>demo01_hello_vscode</name>
  <!-- 版本 -->
  <version>0.0.0</version>
  <!-- 描述信息 -->
  <description>The demo01_hello_vscode package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="[email protected]">Jane Doe</maintainer> -->
  <!-- 维护人员 -->
  <maintainer email="[email protected]">xuzuo</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 -->
  <!-- 许可证信息,ROS核心组件默认 BSD -->
  <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/demo01_hello_vscode</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, but could be -->
  <!-- Example: -->
  <!-- <author email="[email protected]">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_depend>message_generation</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>
  <exec_depend>message_runtime</exec_depend>

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

  </export>
</package>

2. Configure the CMakeLists.txt file

Then configure the CMakeLists.txt file. The CMakeLists.txt file is the input file for the CMake compilation system to compile the software package. The cmake command generates the makefiles file based on the CMakeLists.txt file, and the make command generates an executable file based on the makefiles file compilation link.

find_package mainly fills in other CMake/Catkin packages required for building

find_package(catkin REQUIRED COMPONENTS 
  roscpp
  rospy
  std_msgs
  message_generation
)

add_message_files(), add_service_files(), add_action_files() are mainly message/service/action generators, which need to fill in the relevant message/service/action file names written by yourself

add_message_files(
  FILES
  person.msg
)

generate_messages() is mainly used to generate custom messages such as messages/services/actions, and only needs to fill in the dependency package generated by messages/services/actions

generate_messages(
  DEPENDENCIES
  std_msgs
)

The function of catkin_package() is to specify the build information output of the package, we only need to fill in the packages that are dependent on compilation

catkin_package( 
#  INCLUDE_DIRS include  
#  LIBRARIES ${PROJECT_NAME}   
   CATKIN_DEPENDS roscpp rospy std_msgs message_runtime   
#   DEPENDS eigen opencv
)

For Python code, the installation rules look different because the add_library() and add_executable() functions are not used,catkin_install_python() is used to tell catkin which python files to compile.If you only install Python scripts and don't provide any modules, you don't need to create a setup.py file, and you don't need to configure catkin_python_setup().

catkin_install_python(PROGRAMS 
#  scripts/myscript  
   scripts/turtle_circle.py
   scripts/turtle_pose.py
   scripts/turtle_create.py
   DESTINATION ${
    
    CATKIN_PACKAGE_BIN_DESTINATION}
)

3. Write Python code

Next, we write a topic publishing node to publish the movement news of the little turtle, so that the movement trajectory of the little turtle becomes a circle, and create a new .py file named turtle_circle.py in the scripts directory

#! /usr/bin/python

#1.导包
import rospy
from geometry_msgs.msg import Twist

if __name__ == "__main__":
    # 2.初始化 ROS 节点
    rospy.init_node("turtle_circle")
    # 3.创建发布者对象
    pub = rospy.Publisher("/turtle1/cmd_vel",Twist,queue_size=1000)
    # 4.循环发布运动控制消息
    rate = rospy.Rate(10)
    msg = Twist()
    msg.linear.x = 1.0
    msg.linear.y = 0.0
    msg.linear.z = 0.0
    msg.angular.x = 0.0
    msg.angular.y = 0.0
    msg.angular.z = 0.6

    while not rospy.is_shutdown():
        pub.publish(msg)
        rate.sleep()

Then we write a topic subscription node to obtain the motion status of the little turtle in real time, including linear velocity, angular velocity and pose, and create a new .py file in the scripts directory named turtle_pose.py

#! /usr/bin/python

#1.导包
import rospy
from turtlesim.msg import Pose

def doPose(data):
    rospy.loginfo("乌龟坐标:x=%.2f, y=%.2f,theta=%.2f",data.x,data.y,data.theta)

if __name__ == "__main__":

    # 2.初始化 ROS 节点
    rospy.init_node("sub_pose_p")

    # 3.创建订阅者对象
    sub = rospy.Subscriber("/turtle1/pose",Pose,doPose,queue_size=1000)
    #     4.回调函数处理订阅的数据
    #     5.spin循环
    rospy.spin()

Then we write a service request node to generate a new little turtle, create a new .py file in the scripts directory and name it turtle_create.py

#! /usr/bin/python

#1.导包
import rospy
from turtlesim.srv import Spawn,SpawnRequest,SpawnResponse

if __name__ == "__main__":
    # 2.初始化 ros 节点
    rospy.init_node("set_turtle_p")
    # 3.创建 service 客户端
    client = rospy.ServiceProxy("/spawn",Spawn)
    # 4.等待服务启动
    client.wait_for_service()
    # 5.发送请求
    req = SpawnRequest()
    req.x = 2.5
    req.y = 2.5
    req.theta = 0
    req.name = "turtle2"
    try:
        response = client.call(req)
        # 6.处理响应
        rospy.loginfo("乌龟创建成功!,叫:%s",response.name)
    except expression as identifier:
        rospy.loginfo("服务调用失败")

Remember to add executable permissions to the python file in the terminal

chmod +777 *.py

Then press the shortcut key ctrl + shift + B to invoke compilation, select: catkin_make:build, check if the terminal reports any errors, and it is basically no problem if no errors are reported

4. Configure the launch file

A program may need to start multiple nodes, for example: ROS built-in small turtle case, if you want to control the movement of the turtle and read the movement state, you need to start multiple windows, respectively start roscore, turtle interface node, sports topic release node, sports Topic subscription node. If you call rosrun to start one by one every time, it is obviously inefficient. The official ROS optimization strategy is to use the launch file to start multiple ROS nodes at one time.

node --> a node pkg included
-----> function package
type ----> the node file name to be run
--> name the node
output --> set the output target of the log

Create a new launch folder under the xxx function package, create a new xxx.launch file under the folder, and configure the content of the .launch file

<launch>
    <node pkg="xxx" type="turtle_circle.py" name="run_circle" output="screen" />
    <node pkg="xxx" type="turtle_pose.py" name="run_pose" output="screen" />
    <node pkg="xxx" type="turtle_create.py" name="run_create" output="screen" />
    <node pkg="turtlesim" type="turtlesim_node" name="t1"/>
</launch>

Finally, execute the roslaunch command in the vscode terminal to run the launch script

roslaunch xxx(功能包名) xxx.launch(launch文件名)

Summarize

The above is the entire content of the ROS integrated development and ROS communication study notes. This note briefly introduces the basic construction process of the ROS development environment and the principle learning and test deployment of ROS communication. ROS adopts a distributed framework, mainly because a robot usually includes multiple parts, and each part has a supporting control program to realize the robot's movement and perception functions. Then to coordinate these parts in a robot, or to coordinate a robot cluster composed of multiple robots, it is necessary to enable the dispersed parts to communicate with each other. Solving this distributed communication problem is the original intention of ROS.

Guess you like

Origin blog.csdn.net/m0_55202222/article/details/130415912