记录一些学习内容,方便下来用的时候捡起来
工作空间:文件夹 工作区
建立:
$ mkdir -p ~/dev_ws/src
$ cd ~/dev_ws/src
自动安装依赖:
$ sudo rosdepc init
$ rosdepc update
$ cd ..
$ rosdepc install -i --from-path src --rosdistro humble -y
编译:
$ sudo apt install python3-colcon-ros
$ cd ~/dev_ws/
$ colcon build
生成文件
- src,代码空间,未来编写的代码、脚本,都需要人为的放置到这里;
- build,编译空间,保存编译过程中产生的中间文件;
- install,安装空间,放置编译得到的可执行文件和脚本;
- log,日志空间,编译和运行过程中,保存各种警告、错误、信息等日志。
设置环境变量:
$ source install/local_setup.sh # 仅在当前终端生效
$ echo " source ~/dev_ws/install/local_setup.sh" >> ~/.bashrc # 所有终端均生效
功能包 :实现一些功能 文件夹
创建功能包指令
ros2 pkg create --build-type <build-type> <package_name>
比如在终端中分别创建C++和Python版本的功能包: 后者是功能包的名字
$ cd ~/dev_ws/src
$ ros2 pkg create --build-type ament_cmake learning_pkg_c # C++
$ ros2 pkg create --build-type ament_python learning_pkg_python # Python
编译功能包:
编译功能包
在创建好的功能包中,我们可以继续完成代码的编写,之后需要编译和配置环境变量,才能正常运行:
$ cd ~/dev_ws
$ colcon build # 编译工作空间所有功能包
$ source install/local_setup.bash
节点:执行具体的任务 每个节点是一个可以独立运行的可执行文件 且名字唯一
$ ros2 run learning_node node_helloworld
完成代码的编写后需要设置功能包的编译选项,让系统知道Python程序的入口,打开功能包的setup.py文件,加入如下入口点的配置:
entry_points={
'console_scripts': [
'node_helloworld = learning_node.node_helloworld:main',
'node_helloworld_class = learning_node.node_helloworld_class:main',
],
编程接口初始化->创建节点并初始化->实现节点功能->销毁节点并关闭接口
实例如下:
import rclpy # ROS2 Python接口库
from rclpy.node import Node # ROS2 节点类
import time
"""
创建一个HelloWorld节点, 初始化时输出“hello world”日志
"""
class HelloWorldNode(Node):
def __init__(self, name):
super().__init__(name) # ROS2节点父类初始化
while rclpy.ok(): # ROS2系统是否正常运行
self.get_logger().info("Hello World") # ROS2日志输出
time.sleep(0.5) # 休眠控制循环时间
def main(args=None): # ROS2节点主入口main函数
rclpy.init(args=args) # ROS2 Python接口初始化
node = HelloWorldNode("node_helloworld_class") # 创建ROS2节点对象并进行初始化
rclpy.spin(node) # 循环等待ROS2退出
node.destroy_node() # 销毁节点对象
rclpy.shutdown() # 关闭ROS2 Python接口
话题:节点间传递数据的桥梁 .msg
发布者-订阅者
实现一个发布者,流程如下:
编程接口初始化->创建节点并初始化->创建发布者对象->创建并填充话题消息->发布话题消息->销毁节点并关闭接口
订阅者流程:
编程接口初始化->创建节点并初始化->创建订阅者对象->回调函数处理话题数据->销毁节点并关闭接口
服务:节点间另一种通信机制 你问我答 .srv
客户端-服务端
实现一个客户端,流程如下:
编程接口初始化->创建节点并初始化->创建客户端对象->创建并发送请求数据->等待服务器端应答数据->销毁节点并关闭接口
实现一个服务端,流程如下:
编程接口初始化->创建节点并初始化->创建服务器端对象->通过回调函数处进行服务->向客户端反馈应答结果->销毁节点并关闭接口
动作:话题 服务 动作 是三种通信机制 动作由服务、话题组成 .action
$ ros2 action list # 查看服务列表
$ ros2 action info <action_name> # 查看服务数据类型
$ ros2 action send_goal <action_name> <action_type> <action_data> # 发送服务请求
通信接口:
话题:单向 要说清楚要发送的数据
服务:双向 要说清楚请求和应答的数据 中间---隔开
动作: 目标 结果 反馈
自己创建的接口要在CMakeList.txt中声明(引号)
参数:全局字典 多节点共享数据
参数查询与修改
如果想要查询或者修改某个参数的值,可以在param命令后边跟get或者set子命令:
$ ros2 param describe turtlesim background_b # 查看某个参数的描述信息
$ ros2 param get turtlesim background_b # 查询某个参数的值
$ ros2 param set turtlesim background_b 10 # 修改某个参数的值
参数文件保存与加载
一个一个查询/修改参数太麻烦了,不如试一试参数文件,ROS中的参数文件使用yaml格式,可以在param命令后边跟dump子命令,将某个节点的参数都保存到文件中,或者通过load命令一次性加载某个参数文件中的所有内容:
$ ros2 param dump turtlesim >> turtlesim.yaml # 将某个节点的参数保存到参数文件中
$ ros2 param load turtlesim turtlesim.yaml # 一次性加载某一个文件中的所有参数