# 【ROS教程】ROS文件系统和基础架构

@[TOC](https://github.com/UnderTurrets/notes/blob/master/ROS/%E6%96%87%E7%AB%A0%E7%9B%AE%E5%BD%95/README.md)

***

## 1.工作空间目录

![](https://cdn.jsdelivr.net/gh/UnderTurrets/ImageHosting@master/ros_architecture.jpeg)

```shell
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：编译的基本配置

```

### 1.1 package.xml

* 固定格式

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

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <!-- 维护人员 -->
  <maintainer email="*">XXX</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="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>

```

## 2.启动节点的方式

### 2.1 一次启动一个

```shell
rosrun <the name of package> <the name of executable file>
```

* executable file：对于C语言，这个文件就是CMakeLists.txt中用add\_executable生成的可执行文件；对于python，这个文件就是CMakeLists.txt中用catkin\_install\_python指向的文件

对应语法：

```shell
add_executable(<the name of executable file>
               src/<the name of the source>.cpp
              )
catkin_install_python(PROGRAMS scripts/<the name of the source>.py
                      DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
                     )
```

### 2.2 一次启动多个

如果想要一次性启动一个包里的多个节点，而不是一行行地输入rosrun指令...

* 我们需要一个launch文件，它的固定格式是这样的：

```shell
<launch>
    <node pkg="helloworld" type="demo_hello" name="hello" output="screen" />
    <node pkg="turtlesim" type="turtlesim_node" name="t1"/>
    <node pkg="turtlesim" type="turtle_teleop_key" name="key1" />
</launch>
```

* node：包含的某个节点
* pkg：功能包
* type：被运行的节点文件
* name：为节点命名
* output：设置日志的输出目标

然后，在终端输入：

```shell
roslaunch <the name of package> <the name of launch file>
```

## 3.ROS常用命令

### 3.1 增

创建新的ROS功能包：

```shell
catkin_create_pkg 自定义包名 依赖包
```

### 3.2 查

列出所有功能包：

```shell
rospack list
```

查找某个功能包是否存在，如果存在返回安装路径：

```shell
rospack find 包名
```

### 3.3 执行

#### 3.3.1 加载环境变量

先进入工作目录，然后：

```shell
source ./devel/setup.bash
```

#### 3.3.2 运行节点

`roscore`：ROS的系统先决条件节点和程序的集合，必须运行 roscore 才能使 ROS 节点进行通信。**新开一个终端并输入**：

```shell
roscore #用法一
roscore -p xxxx #用法二，指定端口号
```

roscore 将启动:

* ros master
* ros 参数服务器
* rosout 日志节点

### 3.4 查看计算图

**在节点正在运行的情况下**，终端输入：

```shell
rosrun rqt_graph rqt_graph
```

![](https://cdn.jsdelivr.net/gh/UnderTurrets/ImageHosting@master/ros_rqtgraph.png)

## 4.创建功能包

### 4.1 选择工作目录

首先，选择一个路径作为工作目录。这里我选择了`/home/xu736946693/Desktop/ROS-exercise`作为工作目录

### 4.2 创建功能包目录

```shell
mkdir src
```

然后，**在工作空间目录下**：

```shell
catkin_make
```

src目录下会多出一个锁定的CMakeLists.txt文件，不用管它。

### 4.3 建立功能包

先进入src目录

```shell
cd src
```

然后使用ROS提供的指令直接创建功能包即可：

```shell
catkin_create_pkg <the name of your package> roscpp rospy std_msgs message_generatio
```

**roscpp、rospy、std\_msgs、message\_generatio是你所需要的依赖，你可以自由决定想要哪些依赖**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hanxu.gitbook.io/blogs/ros/ros-jiao-cheng-ros-wen-jian-xi-tong-he-ji-chu-jia-gou.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
