ROS系统
-
ROS2:创建一个包和节点
准备 在ROS2中什么是包,什么是节点? 包(Package) 是 ROS 2 的基本构建单元,包含了代码、资源、配置和依赖,组织着机器人的各个功能模块。 节点(Node) 是 ROS 2 中执行的具体单元,它是一个程序,可以完成传感器读取、控制计算、数据处理等任务,并通过话题、服务或动作与其他节点进行通信。 一个包中可以有多个节点,节点与包是包含的关系。 安装前面的文章安装好ROS2的开发环境。 安装colcon编译工具、rosdep工具。 sudo apt install python3-colcon-ros 创建一个工作空间 mkdir -p ~/dev_ws/src 创建一个功能包的命令 ros2 pkg create --build-type <build-type> <packge_name> pkg:调用功能包相关功能的子命令。 create:创建功能包的子命令。 build-type:表示新创建的功能包是C++还是Python,如果使用C++或者C,这里是"ament_cmake";如果使用python,这里就是"ament_python"。 packege_name:新建功能包的名字。 示例 cd ~/dev_ws/src ros2 pkg create --build-type ament_cmake learning_pkg_cpp ros2 pkg create --build-type ament_python learning_pkg_python 注意执行上面命令时,就会在当前目录下进行创建包,因此为了工程目录的结构,要切换到指定的目录进行创建。 python的方式 创建一个包 cd ~/dev_ws/src/ ros2 pkg create --build-type ament_cmake learning_pkg_python 创建完成后,会产生如下文件 . ├── learning_pkg_python │ ├── learning_pkg_python │ │ └── __init__.py │ ├── package.xml │ ├── resource │ │ └── learning_pkg_python │ ├── setup.cfg │ ├── setup.py │ └── test │ ├── test_copyright.py │ ├── test_flake8.py │ └── test_pep257.py 创建节点程序 在~/dev_ws/src/learning_pkg_python/learning_pkg_python目录下创建一个node_helloworld_class.py文件,实现代码如下: #! /usr/bin/env python3 # -*- coding: utf-8 -*- import rclpy from rclpy.node import Node import time class HelloworldNode(Node): def __init__(self, name): super().__init__(name) while rclpy.ok(): self.get_logger().info("Hello World") time.sleep(0.5) def main(args=None): rclpy.init(args=args) node = HelloworldNode("node_helloworld_class") rclpy.spin(node) node.destroy_node() rclpy.shutdown() 注意node_helloworld_class.py文件要和默认的init.py在一个目录下,保持同级。 设置程序入口 entry_points={ 'console_scripts': [ 'node_helloworld_class = learning_pkg_python.node_helloworld_class:main', ], }, 设置python的程序入口,让ROS2系统知道python程序的入口。 编译 cd ~/dev_ws/ colcon build 编译的时候,要切换到工程的根目录下进行编译。因为编译会在当前的根目录下生成build、install、log,而工程下会有很多包,因此建议都切换到工程的根目录下进行编译。 执行 ros2 run learning_pkg_python node_helloworld_class CPP方式 创建一个包 执行创建包的命令 ros2 pkg create --build-type ament_cmake learning_pkg_cpp 下面是生成的包的目录结构 . ├── learning_pkg_cpp │ ├── CMakeLists.txt │ ├── include │ │ └── learning_pkg_cpp │ ├── package.xml │ └── src 创建节点程序 在learning_pkg_cpp/src目录下创建一个node_helloworld_class.cpp文件,编写代码。 #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" class HelloWorldClass : public rclcpp::Node { public: HelloWorldClass():Node("hello_world_class") { while(rclcpp::ok()) { RCLCPP_INFO(this->get_logger(), "Hello World"); sleep(1); } } }; int main(int argc, char *argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<HelloWorldClass>()); rclcpp::shutdown(); return 0; } 设置编译选项 python是不用编译的,但是C++程序需要编译因此需要更新CmakeLists.txt。在文件中添加一下内容。 find_package(rclcpp REQUIRED) # 查找依赖的功能包rclcpp,提供ROS2 C++的基础接口 add_executable(node_helloworld_class src/node_helloworld_class.cpp) # 添加一个可执行文件名称为node_helloworld_class,源码路径为src/node_helloworld_class.cpp ament_target_dependencies(node_helloworld_class rclcpp) #编译时链接rclcpp的依赖库 install(TARGETS node_helloworld_class DESTINATION lib/${PROJECT_NAME} ) #将可执行文件拷贝到install目录下。 编译执行 # 编译 cd ~/dev_ws/ colcon build # 运行 source install/setup.bash #先执行一下环境变量,可以补全新的命令。 -
ROS2安装:ubuntu 24.04.2上实践
前言 本文在unbuntu 24.10系统上搭建ROS2系统。 No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 24.04.2 LTS Release: 24.04 Codename: noble 设置编码格式 locale # check for UTF-8 sudo apt update && sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 export LANG=en_US.UTF-8 locale # verify settings 添加ROS apt仓库 启用 universe 仓库 sudo apt install software-properties-common sudo add-apt-repository universe 添加 ROS 的 GPG key 和 repository sudo apt update && sudo apt install curl gnupg2 lsb-release sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg 将仓库添加到列表中 echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null 安装ROS 2 下载安装ROS2桌面版软件。 sudo apt update sudo apt upgrade sudo apt install ros-jazzy-desktop 设置环境变量 执行上面的安装命令,没有报错就已经成功安装好ROS2了,默认在/opt路径下。因为要常用到ROS2相关的命令,因此可以添加一下环境变量。 echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc source ~/.bashrc 运行测试用例 在一个终端启动如下命令,表示一个数据的发布者节点发送消息。 ros2 run demo_nodes_cpp talker [INFO] [1757919638.619982839] [talker]: Publishing: 'Hello World: 1' [INFO] [1757919639.619919625] [talker]: Publishing: 'Hello World: 2' [INFO] [1757919640.619874774] [talker]: Publishing: 'Hello World: 3' [INFO] [1757919641.619899411] [talker]: Publishing: 'Hello World: 4' [INFO] [1757919642.619969273] [talker]: Publishing: 'Hello World: 5' [INFO] [1757919643.619894999] [talker]: Publishing: 'Hello World: 6' [INFO] [1757919644.619798092] [talker]: Publishing: 'Hello World: 7' [INFO] [1757919645.619868044] [talker]: Publishing: 'Hello World: 8' [INFO] [1757919646.619927174] [talker]: Publishing: 'Hello World: 9' 在另外一个终端执行一下命令,可以订阅此消息 ros2 run demo_nodes_py listener [INFO] [1757919722.633895350] [listener]: I heard: [Hello World: 85] [INFO] [1757919723.620902142] [listener]: I heard: [Hello World: 86] [INFO] [1757919724.621171224] [listener]: I heard: [Hello World: 87] [INFO] [1757919725.621231371] [listener]: I heard: [Hello World: 88] [INFO] [1757919726.620940203] [listener]: I heard: [Hello World: 89] 如果listener能够正确接收到消息,那么ROS2就已经在系统中安装好了。 -
什么是ROS:机器人操作系统快览随记
环境搭建 catkin vscode ROS插件、bracket pair colorizer 2 terminator sudo apt install terminator CRTL+ALT+T启动 CRTL+SHIFT+E左右分屏 CRTL+SHIFT+O上下分屏 CRTL+SHIFT+W关闭窗口 程序 基础单元node 节点的容器packege,以packege安装节点,packege里面有多个节点。节点不能脱离packege存在。 编写节点步骤 订阅与发布 多个节点直接的信息交互 跟MQTT机制类似。 消息类型,bool、byte、float.......可上官网查看https://index.ros.org 发布者 步骤: 1. 确定话题名称和消息类型 2. 包含消息类型的头文件。 3. 通过NodeHandler大管家发布一个话题获得消息发送对象。 4. 生成要发送的消息包并进行发送数据复制。 5. 调用消息发送对象publish函数发布消息。 常用工具: rostopic list 列出当前系统所有活跃的话题 rostopic echo <主题名称> 显示话题中发送的消息包内容 rostopic hz 查看话题发布频率 订阅者 步骤: 1. 确定话题名称和消息类型。 2. 包含ros.h和消息类型对应头文件。 3. 通过NodeHandler订阅一个话题并设置一个消息接收回调。 4. 定义一个回调函数。 5. main函数中执行ros::spinOnce(),在while循环中可以响应接收消息。 常用工具:rqt_graph 查看ROS中节点,通讯关系。 launch 可以支持一下启动多个节点,使用xml来描述。 使用launch文件,可以通过roslaunch指令一次启动多个节点。 在lauch文件中,为节点添加output="screen"属性,可以让节点信息输出终端。 在launch文件中,为节点添加launch-prefix="gnome-terminal -e"属性,可以让节点单独运行在一个独立终端中。 可以通过launch文件来分析工程代码。 python方式 使用python的方式,只需要开始的时候编译一次,同步一下环境就行,后续就不用编译了,因为python是脚本,不需要编译。 机器的运动控制 线性方向:X,Y,Z坐标值。 角度控制:X,Y,Z方向旋转角度。 使用wbr_simulation,要控制机器人就发送消息就行了,消息类型就是线性方向+角度 要控制对主题/cmd_vel发布指令即可。 RViz 激光雷达原理,发射红外,接收红外,通过光速与时间计算障碍物距离,360°旋转。 Rviz是观测传感器数据,显示到仿真界面中。 激光雷达 激光雷达的数据包格式 float32[] ranges #一个数组,每个角度对应的测试距离。共360 float32[] ranges # 每个角度的信号强度,强度越高对上上面的测试距离越可信 如何获取到雷达测距数据? 使用wbr_simulation,订阅/scan话题即可获取到雷达数据。激光雷达每扫描一圈,就会调用一次注册订阅的话题回调函数。 如何实现运动避障的效果? 订阅/scan获取雷达测试数据,对/cmd_vel主题进行发布控制。当发现测距比较近的时候,就发布控制指令进行调整。 IMU 用于测量空间姿态,也就是陀螺仪。 消息包格式 imu/data_raw( sensor_msgs/Imu):加速度输出的矢量加速度、陀螺仪输出的旋转角速度 imu/data(sensor_msgs/imu):对矢量加速度和旋转角速度融合后的4元素姿态描述。最后可以通过这4元素计算出欧拉角度。 imu/mag(sensor_msgs/MagneticField):磁强计输出数据。 ros中怎么获取数据?订阅/imu/data主题得到4元素,然后通过FT计算欧拉角,得到相对X,Y,Z的旋转角度。 航向锁定的实验 获取到朝向角后,然后通过/cmd_vel发布主题进行控制。 ROS消息包 标准消息包:std_msgs,包含数值类型、数组类型、结构体类型。 常规消息包:common_msgs,包括(sensor_msgs)传感器消息包、(geometry_msgs)几何消息包、(nav_msgs)导航消息包等等。 自定义消息包:根据基本的消息包类型来构建消息。需要按照ros规则来创建一个.msg的文件, rosmsg show xxx显示。 栅格地图:map_server 获取/map主题,获取栅格坐标格式为nav_msgs/OccupancyGird,可以和RVIZ进行联动显示。 SLAM simultaneous localization and mapping 同时定位与地图构建 如何建图原理? 先确定一个参考位置,然后进行移动,每移动一个位置获得一个图,这个图可以是用视觉识别的物体、雷达探测障碍物等方式,然后通过每个位置获得的图进行拼接合并,以此获取到全局的地图。 在ros系统中如何获取地图 激光雷电 发布/scan-> Slam节点获取处理 发布/map->RViz显示 hector_mapping开源的slam算法 TF TransForm描述两个坐标系的空间关系,坐标变化关系。简单理解就是机器人相对参考坐标的位置关系 由TF发布节点,通过/tf主题来发布。 结合里程计的 gmaping建图算法。 导航 详细的官方图 规划器 先使用目标点生成一个导航路线,然后按照导航路线走,在过程中遇到障碍物则进行避障。在move_base中提供了不同风格的规划器拥有规划路线如Dijkstra算法、A*算法。 定位算法 接着需要知道机器人的具体位置,知道具体的位置才能跟着导航路线走,这就需要定位节点如AMCL算法。 代价地图 代价地图,因为导航路线规划有时候的最短路径没有考虑机器人的尺寸,可能会导致机器人沿着墙边走而导致卡住,代价地图就是把障碍物线设置一个虚拟的安全距离(也可以说是把障碍物膨胀变大些)。全局代价地图和全局代价地图。 恢复行为 机器在运动过程中遇到了障碍物导致不能行动,会进入应急机制重新进行规划路线。 局部规划器 DWA、TEB、WpbhLocalPlanner等等。 ACTION action是节点通信的另外一种方式,与订阅/发布不同而是可以双向传输,传输的双方分别是client和Server。client向server发送信息后,server可以持续不断的通知返回信息。 如:可以通过action接口来调用move_base设置导航的功能。client发送导航的目的地,然后server按照目的地运动,client阻塞等待server的回复,当server到达目的时返回结果。 航点的目的地,不用口算、目测;具体的导航目的地可以用插件获取,如waterplus_map_tools。可以将导航插件写到launch。 ROS相机 /image_raw主题:相机原始数据 /image_color:相机的彩色图像 /image_color_rect:畸变校正后的彩色图像。 /camera_info:相机相关的参数。 获取到图像后可以调用opencv处理图像,如果要做目标跟随,可以找出目标的坐标,然后跟随运动。