01 功能包构建工具colcon

安装colcon。colcon其实是一个功能包构建工具,这个工具用来做什么的呢?简单点说就是用来编译代码的。ROS2默认是没有安装colcon的,所以需要执行以下命令:

1
sudo apt-get install python3-colcon-common-extensions

安装完成后,打开终端输入colcon即可看到其使用方法。

1
colcon -h

02 如何使用 colcon

ROS2与ROS1一样,编写程序都依赖工作空间(worksapce,简写ws)。

1
2
3
4
5
mkdir -p ws_helloworld/src
cd ws_helloworld

# 编译
colcon build

上述命令执行完毕,在 ws_helloworld 目录下包含 build install log src 四个子级目录。

03 创建节点 Helloworld

[!note] ROS2编写程序流程
亘古不变的5步:

  1. 创建功能包
  2. 编辑源文件
  3. 编辑配置文件
  4. 编译
  5. 执行

3.1 Helloworld C++

3.1.1 创建功能包

1
2
3
cd ./ws_helloworld/src
# 创建功能包
ros2 pkg create pkg_helloworld_cpp --build-type ament_cmake --dependencies rclcpp --node-name helloworld

进入功能包文件夹:

1
cd pkg_helloworld_cpp/

可以看到,刚刚自动生成了:源码文件夹src 和源码文件 src/helloworld.cpp;生成配置文件 CMakeLists.txtpackage.xml;还有include 文件夹。

3.1.2 编辑源文件

发现创建了一个 pkg_helloworld_cpp/src/helloworld.cpp ,这个就是源文件。

源文件编写流程:

  1. 包含头文件
  2. 初始化ROS2客户端
  3. 创建节点指针
  4. 各种操作(比如,输出日志)
  5. 释放资源

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
// POP:面向过程编程
// 不推荐

#include "rclcpp/rclcpp.hpp"

int main(int argc, char ** argv){
rclcpp::init(argc,argv);
auto node = rclcpp::Node::make_shared("helloworld_node");
RCLCPP_INFO(node->get_logger(), "helloworld!");
rclcpp::shutdown();
return 0;
}

推荐使用OOP方式:面向对象编程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "rclcpp/rclcpp.hpp"

class HelloNode : public rclcpp::Node
{

public:
HelloNode(std::string name) : Node(name)
{
RCLCPP_INFO(this->get_logger(), "Hello world! I am %s!",name.c_str());
}

private:

};

int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
auto node = std::make_shared<HelloNode>("Thomas");
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}

3.1.3 编辑配置文件

先保持默认不变。简单看一眼配置文件。

3.1.3.1 package.xml

to do

3.1.3.2 CMakeLists.txt

to do

3.1.4 编译

1
colcon build

3.1.5 执行

在工作空间下,执行如下指令:

1
2
3
4
. install/setup.bash

# ros2 run <packegeName> <nodeName>
ros2 run pkg_helloworld_cpp helloworld

3.2 Helloworld Python

3.2.1 创建功能包

1
2
3
cd ./ws_helloworld/src
# 创建功能包
ros2 pkg create pkg_helloworld_py --build-type ament_python --dependencies rclpy --node-name helloworld

进入功能包文件夹:

1
cd pkg_helloworld_py/

可以看到,刚刚自动生成了:源码文件包 pkg_helloworld_py ,其中有__init__.py 和源码文件 helloworld.py;生成配置文件 setup.pypackage.xml;还有resource 文件夹。

3.2.2 编辑源文件

发现创建了一个 pkg_helloworld_py/src/helloworld.py ,这个就是源文件。

源文件编写流程:

  1. 包含头文件
  2. 初始化ROS2客户端
  3. 创建节点指针
  4. 各种操作(比如,输出日志)
  5. 释放资源

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
## POP: 面向过程编程
## 不推荐

import rclpy

def main():
rclpy.init()
node = rclpy.create_node("helloworld_py_node")
node.get_logger().info("hello world! from pkg_helloworld_py")
rclpy.shutdown()

if __name__ == '__main__':
main()

推荐使用OOP方式:面向对象编程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
## OOP:面向对象编程
## 推荐

import rclpy
from rclpy.node import Node

class HelloNode(Node):
"""
创建一个HelloNode节点,并在初始化时输出一个话
"""
def __init__(self,name):
super().__init__(name)
self.get_logger().info("Hello world! I am %s!" % name)

def main(args=None):
rclpy.init(args=args) # 初始化rclpy
node = HelloNode("Thomas") # 新建一个节点
rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
rclpy.shutdown() # 关闭rclpy

if __name__ == '__main__':
main()

3.2.3 编辑配置文件

先保持默认不变。简单看一眼配置文件。

3.2.3.1 package.xml

to do

3.2.3.2 setup.py

添加 entry_point:

1
2
3
4
5
entry_points={
'console_scripts': [
'helloworld = pkg_helloworld_py.helloworld:main'
],
},

3.2.4 编译

1
colcon build

3.2.5 执行

在工作空间下,执行如下指令:

1
2
3
4
. install/setup.bash

# ros2 run <packegeName> <nodeName>
ros2 run pkg_helloworld_py helloworld

3.3 初始化和资源释放

Q:初始化(init) 与 资源释放(shutdown) 在程序中起什么作用?
A:初始化创建 Context 对象,资源释放就是销毁 Context 对象

04 ROS2的文件系统

to do

05 常用工具

5.1 命令行工具

ROS2 的文件系统核心是功能包,我们可以通过编译指令 colcon 和 ros2 内置的工具指令 ros2 来实现功能包的创建、编译、查找与执行等相关操作。

1
2
3
# 创建

ros2 pkg create <packageName> --build-type <ament_cmake/ament_python> --dependencies <rclcpp/rclpy/...> --node-name <nodeName>
1
2
3
4
# 编译

colcon build
colcon build --package-select <packageName>
1
2
3
4
5
# 查找
ros2 pkg executables [包名] # 输出所有功能包或指定功能包下的可执行程序。
ros2 pkg list # 列出所有功能包
ros2 pkg prefix 包名 # 列出功能包路径
ros2 pkg xml # 输出功能包的 package.xml 内容
1
2
# 执行
ros2 run <packageName> <nodeName> <parameters>

5.2 可视化工具

略。