当前位置: 首页 > news >正文

ROS2学习

前言

本篇文章属于ROS2humble的学习笔记,来源于B站鱼香ROSup主。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。

《ROS 2机器人开发从入门到实践》课程介绍_哔哩哔哩_bilibili

 一、Python节点的订阅和发布

1.下载小说,并通过话题间隔5s发送一行

(1)创建工作空间

在终端中输入:

mkdir -p topic_ws/src

(2)在src目录下创建软件包

处于src目录下,在终端中输入:

ros2 pkg create demo_python_topic --build-type ament_python --dependencies rclpy example_interfaces --license Apache-2.0

回到topic_ws目录下,再输入:

colcon build                 构建文件

 (3)在有__init__.py文件的目录下创建节点文件novel_pub_node.py,节点代码部分如下

import rclpy
from rclpy.node import Node
import requests
from example_interfaces.msg import String
from queue import Queueclass NovelNode(Node):def __init__(self, node_name):super().__init__(node_name)self.get_logger().info(f'{node_name},启动!')self.novel_queue = Queue()  #创建队列self.novel_publisher = self.create_publisher(String, 'novel', 100)self.create_timer(5, self.timer_callback)def timer_callback(self):if self.novel_queue.qsize()>0:line = self.novel_queue.get()msg = String()msg.data = lineself.novel_publisher.publish(msg)self.get_logger().info(f'发布了:{msg}')def download(self, url):responese = requests.get(url)responese.encoding = 'utf-8'text = responese.textself.get_logger().info(f'下载{url},{len(text)}')for line in text.splitlines():self.novel_queue.put(line)def main():rclpy.init()node = NovelNode('novel_pub')node.download('https://fanqienovel.com/reader/7173216089122439711?enter_from=page')rclpy.spin(node)rclpy.shutdown()

(4)执行代码

先找到

entry_points={

'console_scripts': [

],

},

改为

entry_points={

        'console_scripts': [

                'novel_pub_node=demo_python_topic.novel_pub_node:main'

],

},

等号左边是可执行文件的名字,等号右边是软件包名和节点名

然后回到 topic_ws目录下,再输入:

colcon build                 构建文件

再在终端中输入source install/setup.bash

修改一下环境变量

再运行即可:ros2 run demo_python_topic novel_pub_node

2.订阅小说并合成语音

import espeakng
import rclpy
from rclpy.node import Node
from example_interfaces.msg import String
from queue import Queue
import threading
import timeclass NovelSubNode(Node):def __init__(self, node_name):super().__init__(node_name)self.get_logger().info(f'{node_name},启动!')self.novel_queue = Queue()self.create_subscription(String, 'novel', self.novel_callback, 10)self.speech_thread_ = threading.Thread(target=self.speaker_thread)self.speech_thread_.start()def novel_callback(self, msg):self.novel_queue.put(msg.data)passdef speaker_thread(self):speaker = espeakng.Speaker()speaker.voice = 'zh'while rclpy.ok():   #检测ROS当前上下文是否okif self.novel_queue.qsize()>0:text = self.novel_queue.get()self.get_logger().info(f'朗读:{text}')speaker.say(text)       #说speaker.wait()        #等说完else:#让当前线程休眠1stime.sleep(1)def main():rclpy.init()node = NovelSubNode('novel_sub')rclpy.spin(node)rclpy.shutdown()

espeakng为朗读引入的库

注意当前线程休眠1s的操作很关键,这能降低CPU功耗

 二、C++节点的订阅和发布

1.发布速度控制海龟画圆

(1)在工作空间的src目录下创建软件包

处于src目录下,在终端中输入:

ros2 pkg create demo_cpp_topic --build-type ament_cmake --dependencies rclcpp geometry_msgs turtlesim  --license Apache-2.0

(2)在软件包下的src目录下创建节点文件turtle_circle.cpp

出现该报错要配置includePath

配置成这样即可

节点代码如下:

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include <chrono>using namespace std::chrono_literals;class TurtleCircleNode: public rclcpp::Node
{
private:rclcpp::TimerBase::SharedPtr timer_;rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr publisher_;//发布者的共享指针public:explicit TurtleCircleNode(const std::string& node_name):Node(node_name){publisher_ = this->create_publisher<geometry_msgs::msg::Twist>("/turtle1/cmd_vel",10);timer_ = this->create_wall_timer(1000ms,std::bind(&TurtleCircleNode::timer_callback,this));}void timer_callback(){auto msg = geometry_msgs::msg::Twist();msg.linear.x = 1.0;msg.angular.z = 0.5;publisher_->publish(msg);}
}; int main(int argc,char *argv[])
{rclcpp::init(argc,argv);auto node = std::make_shared<TurtleCircleNode>("turtle_circle");rclcpp::spin(node);rclcpp::shutdown();return 0;
}

(4)执行代码

首先去CMakeLists文件

add_executable(turtle_circle src/turtle_circle.cpp) #添加可执行文件

ament_target_dependencies(turtle_circle rclcpp geometry_msgs)        #添加依赖

install(TARGETS turtle_circle

DESTINATION lib/${PROJECT_NAME}

) #拷贝文件到人ros2 run的文件目录上,便于ros2 run启动

 然后回到topic_ws工作空间下colcon build 编译文件

生成完后输入source install/setup.bash配置环境变量

ros2 run demo_cpp_topic turtle_circle 即可运行

2.订阅pose实现闭环控制

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include <chrono>
#include "turtlesim/msg/pose.hpp"using namespace std::chrono_literals;class TurtleControlNode: public rclcpp::Node
{
private:rclcpp::TimerBase::SharedPtr timer_;rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr publisher_;//发布者的共享指针rclcpp::Subscription<turtlesim::msg::Pose>::SharedPtr subscriber_;//订阅者的共享指针double target_x_{1.0};double target_y_{1.0};double k{0.5};double max_speed_{3.0};public:explicit TurtleControlNode(const std::string& node_name):Node(node_name){publisher_ = this->create_publisher<geometry_msgs::msg::Twist>("/turtle1/cmd_vel",10);subscriber_ = this->create_subscription<turtlesim::msg::Pose>("/turtle1/pose",10,std::bind(&TurtleControlNode::sub_callback,this,std::placeholders::_1));// timer_ = this->create_wall_timer(1500ms,std::bind(&TurtleControlNode::timer_callback,this));}void sub_callback(const turtlesim::msg::Pose::SharedPtr pose){//1. 获取当前位置auto current_x = pose->x;auto current_y = pose->y;RCLCPP_INFO(get_logger(),"当前:x=%f,y=%f",current_x,current_y);//2. 计算当前海龟位置跟目标位置之间的距离差和角度差auto distance = std::sqrt((target_x_-current_x)*(target_x_-current_x)+(target_y_-current_y)*(target_y_-current_y));auto angle = std::atan2((target_y_-current_y),(target_x_-current_x))-pose->theta;//3.控制策略auto msg = geometry_msgs::msg::Twist();if (distance>0.1){if (fabs(angle)>0.2){msg.angular.z = k*angle;}else{msg.linear.x = k*distance;}}//4.限制速度if (msg.linear.x > max_speed_){msg.linear.x = max_speed_;}publisher_->publish(msg);}
}; int main(int argc,char *argv[])
{rclcpp::init(argc,argv);auto node = std::make_shared<TurtleControlNode>("turtle_control");rclcpp::spin(node);rclcpp::shutdown();return 0;
}


http://www.mrgr.cn/news/91989.html

相关文章:

  • 计算机视觉:主流数据集整理
  • Golang深度学习
  • cline通过硅基流动平台接入DeepSeek-R1模型接入指南
  • Spring使用三级缓存解决循环依赖的源码分析。
  • Redis基础学习
  • STM32-心知天气项目
  • nodejs:express + js-mdict 作为后端,vue 3 + vite 作为前端,在线查询英汉词典
  • 大模型WebUI:Gradio全解12——LangChain原理及其agent构建Gradio(1)
  • JDBC学习
  • 【c语言】函数_作业详解
  • 嵌入式八股文(四)计算机网络篇
  • LTO优化详解
  • FFMPEG编码容错处理解决办法之途径----升级库文件
  • 类与对象(4)
  • 探索YOLO技术:目标检测的高效解决方案
  • windows的CMD命令提示符
  • 政安晨【零基础玩转各类开源AI项目】DeepSeek 多模态大模型Janus-Pro-7B,本地部署!支持图像识别和图像生成
  • ubuntu新系统使用指南
  • 1.vue使用vite构建初始化项目
  • java开发——为什么要使用动态代理?