ros2-7.5 做一个自动巡检机器人

7.5.1 需求及设计

又到了小鱼老师带着做最佳实践项目了。需求:做一个在各个房间不断巡逻并记录图像的机器人。

到达目标点后首先通过语音播放到达目标点信息,

再通过摄像头拍摄一张图片保存到本地。

7.5.2 编写巡检控制节点

在chapt7_ws/src下新建功能包,添加rclpy和nav2_simple_commander依赖。

目录src/autopartol_robot/autopartol_robot/新建文件patrol_node.py

from geometry_msgs.msg import PoseStamped,Pose
from nav2_simple_commander.robot_navigator import BasicNavigator,TaskResult
import rclpy
from rclpy.node import Node
import rclpy.time
from tf2_ros import TransformListener, Buffer #坐标监听器
from tf_transformations import quaternion_from_euler,euler_from_quaternion# 欧拉角转换


class PatrolNode(BasicNavigator):
    def __init__(self,node_name='patrol_node'):
        super().__init__(node_name)
        self.buffer_ = Buffer()
        self.listner_ = TransformListener(self.buffer_,self)
        #声明相关参数
        self.declare_parameter('initial_point',[0.0, 0.0, 0.0])
        self.declare_parameter('target_points',[0.0, 0.0, 0.0, 1.0, 1.0, 1.57])
        self.initial_point_ = self.get_parameter('initial_point').value
        self.initial_points_= self.get_parameter('target_points').value

    def get_pose_by_xyyaw(self, x, y, yaw):
        # 通过x,y,yaw return PoseStamped对象     
        pose = PoseStamped()
        pose.header.frame_id = 'map'
        pose.pose.position.x = x
        pose.pose.position.y = y
        quat = quaternion_from_euler(0,0,yaw)
        pose.pose.orientation.x =quat[0]
        pose.pose.orientation.y =quat[1]
        pose.pose.orientation.z =quat[2]
        pose.pose.orientation.w =quat[3]
        return pose
    def init_robot_pose(self):
        #初始化机器人位姿
        self.initial_point_ = self.get_parameter('initial_point').value
        init_pose = self.get_pose_by_xyyaw(self.initial_point_[0],self.initial_point_[1],self.initial_point_[2]) 
        self.setInitialPose(init_pose)
        self.waitUntilNav2Active()#等待导航可用

    def get_target_points(self):
        #通过参数值获取目标点集合
        points = []
        self.target_points_ = self.get_parameter('target_points').value
        for index in range(int(len(self.target_points_)/3)):
            x = self.target_points_[index*3]
            y = self.target_points_[index*3+1]
            yaw = self.target_points_[index*3+2]
            points.append([x,y,yaw])
            self.get_logger().info(f'获取到目标点:{index}->{x},{y},{yaw}')
        return points    

    def nav_to_pose(self,target_pose):
        #导航到指定位姿
        self.waitUntilNav2Active()
        self.goToPose(target_pose)
        while not self.isTaskComplete():
            feedback = self.getFeedback()
            self.get_logger().info(f'剩余距离:{feedback.distance_remaining }')
        reslut = self.getResult()
        self.get_logger().info(f'导航结果:{reslut}')    

    def get_cuurent_pose(self):
        #通过TF获取当前位姿
        while rclpy.ok():
            try:
                result = self.buffer_.lookup_transform('map','base_footprint',
                        rclpy.time.Time(seconds=0),rclpy.time.Duration(seconds=1))
                transform = result.transform
                self.get_logger().info(f'平移:{transform.translation}')
                # self.get_logger().info(f'旋转:{transform.rotation}')
                # ratation_euler = euler_from_quaternion([
                #     transform.rotation.x,
                #     transform.rotation.y,
                #     transform.rotation.z,
                #     transform.rotation.w]
                # )
                # self.get_logger().info(f'平移rpy:{ratation_euler}')
                return transform
            except Exception as e:
                self.get_logger().warn(f'获取坐标转换异常{str(e)}')

def main():
    rclpy.init()
    patrol = PatrolNode() #节点
    patrol.initial_pose()

    while rclpy.ok():
        points = patrol.get_target_points()
        for point in points:
            x,y,yaw = point[0],point[1],point[2]
            target_pose = patrol.get_pose_by_xyyaw(x,y,yaw)
            patrol.nav_to_pose(target_pose)
    rclpy.shutdown()        

基本上吧之前的单接口调用综合起来。

为方便参数配置,在src/autopartol_robot/新建目录config,新增配置文件

patrol_config.yaml

patrol_node:
  ros__parameters:
    initial_point: [0.0, 0.0, 0.0]
    target_points: [
      0.0,0.0,0.0,
      1.0,2.0,3.14,
      -4.5,1.5,1.57,
      -8.0,-5.0,1.57,
      1.0,-5.0,3.14,
      ]

注意目标点的选取是机器人可达的位置,不能选到障碍物。

启动gazebo模拟器,启动nav2.

再启动patrol_node

 ros2 run autopartol_robot patrol_node --ros-args --params-file /home/bohu/chapt7/chapt7_ws/install/autopartol_robot/share/autopartol_robot/config/patrol_config.yaml

会发现等一会开始初始化地图后,开始沿着设定目标点运动。效果如下

也有异常情况,机器人靠墙太近,gazebo看出距离墙还有段距离,但是在rviz里面局部代价地图有一点变形,导致机器以为有障碍物卡住的现象。

7.5.3 添加语音播报功能

在chatpt7_ws/src下新建功能包autopatrol_interfaces,功能包下新建目录srv,srv新新建接口文件

speachText.srv

string text    # 合成文字
---
bool result    # 合成结果

在CMakeLists.txt注册,并在package.xml添加标签

<member_of_group>rosidl_interface_packages</member_of_group>

重新构建

src/autopartol_robot/autopartol_robot/目录下新建文件speaker.py

import rclpy
from rclpy.node import Node
from autopatrol_interfaces.srv import SpeachText
import espeakng


class Speaker(Node):
    def __init__(self):
        super().__init__('speaker')
        self.speech_service_ = self.create_service(SpeachText,'speech_text',
                                                   self.speech_text_callback)
        self.speaker_ = espeakng.Speaker()
        self.speaker_.voice ='zh'

    def speech_text_callback(self,request,response):
        self.get_logger().info(f'正在朗读 {request.text}')
        self.speaker_.say(request.text)
        self.speaker_.wait()
        response.result = True
        return response
    
def main():
    rclpy.init()
    node = Speaker()
    rclpy.spin(node)
    rclpy.shutdown()

修改patrol_node.py,增加语音合成调用

from geometry_msgs.msg import PoseStamped,Pose
from nav2_simple_commander.robot_navigator import BasicNavigator,TaskResult
import rclpy
from rclpy.node import Node
import rclpy.time
from tf2_ros import TransformListener, Buffer #坐标监听器
from tf_transformations import quaternion_from_euler,euler_from_quaternion# 欧拉角转换
from autopatrol_interfaces.srv import SpeachText


class PatrolNode(BasicNavigator):
    def __init__(self,node_name='patrol_node'):
        super().__init__(node_name)
        self.buffer_ = Buffer()
        self.listner_ = TransformListener(self.buffer_,self)
        #声明相关参数
        self.declare_parameter('initial_point',[0.0, 0.0, 0.0])
        self.declare_parameter('target_points',[0.0, 0.0, 0.0, 1.0, 1.0, 1.57])
        self.initial_point_ = self.get_parameter('initial_point').value
        self.initial_points_= self.get_parameter('target_points').value
        self.speech_client_ = self.create_client(SpeachText,'speech_text')

    def get_pose_by_xyyaw(self, x, y, yaw):
        # 通过x,y,yaw return PoseStamped对象     
        pose = PoseStamped()
        pose.header.frame_id = 'map'
        pose.pose.position.x = x
        pose.pose.position.y = y
        quat = quaternion_from_euler(0,0,yaw)
        pose.pose.orientation.x =quat[0]
        pose.pose.orientation.y =quat[1]
        pose.pose.orientation.z =quat[2]
        pose.pose.orientation.w =quat[3]
        return pose
    def init_robot_pose(self):
        #初始化机器人位姿
        self.initial_point_ = self.get_parameter('initial_point').value
        init_pose = self.get_pose_by_xyyaw(self.initial_point_[0],self.initial_point_[1],self.initial_point_[2]) 
        self.setInitialPose(init_pose)
        self.waitUntilNav2Active()#等待导航可用

    def get_target_points(self):
        #通过参数值获取目标点集合
        points = []
        self.target_points_ = self.get_parameter('target_points').value
        for index in range(int(len(self.target_points_)/3)):
            x = self.target_points_[index*3]
            y = self.target_points_[index*3+1]
            yaw = self.target_points_[index*3+2]
            points.append([x,y,yaw])
            self.get_logger().info(f'获取到目标点:{index}->{x},{y},{yaw}')
        return points    

    def nav_to_pose(self,target_pose):
        #导航到指定位姿
        self.waitUntilNav2Active()
        self.goToPose(target_pose)
        while not self.isTaskComplete():
            feedback = self.getFeedback()
            self.get_logger().info(f'剩余距离:{feedback.distance_remaining }')
        reslut = self.getResult()
        self.get_logger().info(f'导航结果:{reslut}')    

    def get_cuurent_pose(self):
        #通过TF获取当前位姿
        while rclpy.ok():
            try:
                result = self.buffer_.lookup_transform('map','base_footprint',
                        rclpy.time.Time(seconds=0),rclpy.time.Duration(seconds=1))
                transform = result.transform
                self.get_logger().info(f'平移:{transform.translation}')
                # self.get_logger().info(f'旋转:{transform.rotation}')
                # ratation_euler = euler_from_quaternion([
                #     transform.rotation.x,
                #     transform.rotation.y,
                #     transform.rotation.z,
                #     transform.rotation.w]
                # )
                # self.get_logger().info(f'平移rpy:{ratation_euler}')
                return transform
            except Exception as e:
                self.get_logger().warn(f'获取坐标转换异常{str(e)}')
    def speech_text(self,text):
        #调用服务合成语音
        while not self.speech_client_.wait_for_service(timeout_sec=1):
            self.get_logger().info("wait for speech service")
        request = SpeachText.Request()
        request.text = text
        future = self.speech_client_.call_async(request)
        rclpy.spin_until_future_complete(self,future)
        if future.result() is not None:
            result = future.result().result
            if result:
                self.get_logger().info(f'语音合成成功:{text}')
            else:
                self.get_logger().warn(f'语音合成失败:{text}')
        else:
            self.get_logger().warn('语音合成服务请求失败')

def main():
    rclpy.init()
    patrol = PatrolNode() #节点
    patrol.speech_text('正在准备初始化位置')
    patrol.init_robot_pose()
    patrol.speech_text('初始化位置完成')

    while rclpy.ok():
        points = patrol.get_target_points()
        for point in points:
            x,y,yaw = point[0],point[1],point[2]
            target_pose = patrol.get_pose_by_xyyaw(x,y,yaw)
            patrol.speech_text(text=f'准备前往目标点{x},{y}')
            patrol.nav_to_pose(target_pose)
    rclpy.shutdown()        

效果跟上面类似,日志输出多了语音的

[speaker-2] [INFO] [1737017187.818829250] [speaker]: 正在朗读 准备前往目标点1.0,2.0
[patrol_node-1] [INFO] [1737017191.194245817] [patrol_node]: 语音合成成功:准备前往目标点1.0,2.0
[patrol_node-1] [INFO] [1737017195.311579068] [patrol_node]: Nav2 is ready for use!
[patrol_node-1] [INFO] [1737017195.314096555] [patrol_node]: Navigating to goal: 1.0 2.0...
[patrol_node-1] [INFO] [1737017195.509438991] [patrol_node]: 剩余距离:0.2445448786020279
[patrol_node-1] [INFO] [1737017195.612344544] [patrol_node]: 剩余距离:2.230710744857788
[patrol_node-1] [INFO] [1737017195.716231929] [patrol_node]: 剩余距离:2.230710744857788
[patrol_node-1] [INFO] [1737017195.819218225] [patrol_node]: 剩余距离:2.230710744857788
[patrol_node-1] [INFO] [1737017195.923079415] [patrol_node]: 剩余距离:2.230710744857788 

7.5.4订阅图像并记录

from geometry_msgs.msg import PoseStamped,Pose
from nav2_simple_commander.robot_navigator import BasicNavigator,TaskResult
import rclpy
from rclpy.node import Node
import rclpy.time
from tf2_ros import TransformListener, Buffer #坐标监听器
from tf_transformations import quaternion_from_euler,euler_from_quaternion# 欧拉角转换
from autopatrol_interfaces.srv import SpeachText
from sensor_msgs.msg import Image #消息接口
from cv_bridge import CvBridge #图像转换
import cv2 #保存图像


class PatrolNode(BasicNavigator):
    def __init__(self,node_name='patrol_node'):
        super().__init__(node_name)
        self.buffer_ = Buffer()
        self.listner_ = TransformListener(self.buffer_,self)
        #声明相关参数
        self.declare_parameter('initial_point',[0.0, 0.0, 0.0])
        self.declare_parameter('target_points',[0.0, 0.0, 0.0, 1.0, 1.0, 1.57])
        self.initial_point_ = self.get_parameter('initial_point').value
        self.initial_points_= self.get_parameter('target_points').value
        self.speech_client_ = self.create_client(SpeachText,'speech_text')
         # 订阅与保存图像相关定义
        self.declare_parameter('image_save_path', '')
        self.image_save_path = self.get_parameter('image_save_path').value
        self.bridge = CvBridge()
        self.latest_img_ = None
        self.image_sub_ = self.create_subscription(Image,'/camera_sensor/image_raw',self.img_callback,1)

    def img_callback(self,msg):
        self.latest_img_ = msg

    def record_img(self):
        if self.latest_img_ is not Node:
           pose = self.get_cuurent_pose()
           cv_image = self.bridge.imgmsg_to_cv2(self.latest_img_)
           cv2.imwrite(f'{self.image_save_path}img_{pose.translation.x:3.2f}_{pose.translation.y:3.2f}.png',
                       cv_image)   

    def get_pose_by_xyyaw(self, x, y, yaw):
        # 通过x,y,yaw return PoseStamped对象     
        pose = PoseStamped()
        pose.header.frame_id = 'map'
        pose.pose.position.x = x
        pose.pose.position.y = y
        quat = quaternion_from_euler(0,0,yaw)
        pose.pose.orientation.x =quat[0]
        pose.pose.orientation.y =quat[1]
        pose.pose.orientation.z =quat[2]
        pose.pose.orientation.w =quat[3]
        return pose
    def init_robot_pose(self):
        #初始化机器人位姿
        self.initial_point_ = self.get_parameter('initial_point').value
        init_pose = self.get_pose_by_xyyaw(self.initial_point_[0],self.initial_point_[1],self.initial_point_[2]) 
        self.setInitialPose(init_pose)
        self.waitUntilNav2Active()#等待导航可用

    def get_target_points(self):
        #通过参数值获取目标点集合
        points = []
        self.target_points_ = self.get_parameter('target_points').value
        for index in range(int(len(self.target_points_)/3)):
            x = self.target_points_[index*3]
            y = self.target_points_[index*3+1]
            yaw = self.target_points_[index*3+2]
            points.append([x,y,yaw])
            self.get_logger().info(f'获取到目标点:{index}->{x},{y},{yaw}')
        return points    

    def nav_to_pose(self,target_pose):
        #导航到指定位姿
        self.waitUntilNav2Active()
        self.goToPose(target_pose)
        while not self.isTaskComplete():
            feedback = self.getFeedback()
            self.get_logger().info(f'剩余距离:{feedback.distance_remaining }')
        reslut = self.getResult()
        self.get_logger().info(f'导航结果:{reslut}')    

    def get_cuurent_pose(self):
        #通过TF获取当前位姿
        while rclpy.ok():
            try:
                result = self.buffer_.lookup_transform('map','base_footprint',
                        rclpy.time.Time(seconds=0),rclpy.time.Duration(seconds=1))
                transform = result.transform
                self.get_logger().info(f'平移:{transform.translation}')
                # self.get_logger().info(f'旋转:{transform.rotation}')
                # ratation_euler = euler_from_quaternion([
                #     transform.rotation.x,
                #     transform.rotation.y,
                #     transform.rotation.z,
                #     transform.rotation.w]
                # )
                # self.get_logger().info(f'平移rpy:{ratation_euler}')
                return transform
            except Exception as e:
                self.get_logger().warn(f'获取坐标转换异常{str(e)}')
    def speech_text(self,text):
        #调用服务合成语音
        while not self.speech_client_.wait_for_service(timeout_sec=1):
            self.get_logger().info("wait for speech service")
        request = SpeachText.Request()
        request.text = text
        future = self.speech_client_.call_async(request)
        rclpy.spin_until_future_complete(self,future)
        if future.result() is not None:
            result = future.result().result
            if result:
                self.get_logger().info(f'语音合成成功:{text}')
            else:
                self.get_logger().warn(f'语音合成失败:{text}')
        else:
            self.get_logger().warn('语音合成服务请求失败')

def main():
    rclpy.init()
    patrol = PatrolNode() #节点
    patrol.speech_text('正在准备初始化位置')
    patrol.init_robot_pose()
    patrol.speech_text('初始化位置完成')

    while rclpy.ok():
        points = patrol.get_target_points()
        for point in points:
            x,y,yaw = point[0],point[1],point[2]
            target_pose = patrol.get_pose_by_xyyaw(x,y,yaw)
            patrol.speech_text(text=f'准备前往目标点{x},{y}')
            patrol.nav_to_pose(target_pose)
            patrol.speech_text(text=f'已到达目标点{x},{y},准备记录图像')
            patrol.record_img()
            patrol.speech_text(text=f'图像记录完成')
    rclpy.shutdown()        

重新构建后运行,拍照效果如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/956076.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

告别繁琐编译!make和makefile的便捷之道

Linux系列 文章目录 Linux系列前言一、make/makefile是什么&#xff1f;二、make/makefile的使用2.1、语法规则2.2、依赖关系和依赖方法2.3、清理可执行文件2.4、执行依据 三、循环依赖问题总结 前言 上一篇博客给大家分享了在Linux下编译源代码的两个工具&#xff0c;gcc和g…

【鸿蒙】0x02-LiteOS-M基于Qemu RISC-V运行

OpenHarmony LiteOS-M基于Qemu RISC-V运行 系列文章目录更新日志OpenHarmony技术架构OH技术架构OH支持系统类型轻量系统&#xff08;mini system&#xff09;小型系统&#xff08;small system&#xff09;标准系统&#xff08;standard system&#xff09; 简介环境准备安装QE…

C语言初阶习题【29】杨氏矩阵

1. 题目描述——杨氏矩阵 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N); 2. 思路 3. 代码实现1 #include<stdio.h>void fin…

Cloud Foundry,K8S,Mesos Marathon弹性扩缩容特性对比

一、Cloud Foundry 使用Scaling an Application Using App Autoscaler插件&#xff0c;基于资源使用情况触发简单扩缩容 CPU、内存、Http带宽、延时等 监控这些资源的使用情况决定扩缩容策略&#xff1a;实例是增加还是减少 Instance Limits 限制实例数量范围&#xff0c;定义…

中职网络建设与运维ansible服务

ansible服务 填写hosts指定主机范围和控制节点后创建一个脚本&#xff0c;可以利用简化脚本 1. 在linux1上安装系统自带的ansible-core,作为ansible控制节点,linux2-linux7作为ansible的受控节点 Linux1 Linux1-7 Yum install ansible-core -y Vi /etc/ansible/hosts 添加…

【BUUCTF】[GXYCTF2019]BabySQli

进入页面如下 尝试万能密码注入 显示这个&#xff08;qyq&#xff09; 用burp suite抓包试试 发现注释处是某种编码像是base编码格式 MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5 可以使用下面这个网页在线工具很方便…

迅为瑞芯微RK3562开发板/核心板应用于人脸跟踪、身体跟踪、视频监控、自动语音识别(ASR)、图像分类驾驶员辅助系统(ADAS)...

可应用于人脸跟踪、身体跟踪、视频监控、自动语音识别(ASR)、图像分类驾驶员辅助系统(ADAS)、车牌识别、物体识别等。iTOP-3562开发板/核心板采用瑞芯微RK3562处理器&#xff0c;内部集成了四核A53Mali G52架构&#xff0c;主频2GHZ&#xff0c;内置1TOPSNPU算力&#xff0c;RK…

蓝桥杯单片机基础部分——5、DS18B20温度传感器

前言 好久没有更新关于蓝桥杯单片机相关的模块了&#xff0c;今天更新一下数字温度传感器DS18B20的相关应用 单线数字温度计DS1820介绍 DS1820数字温度计提供9位(二进制)温度读数&#xff0c;指示器件的温度。信息经过单线接口送入DS1820 或从 DS1820 送出&#xff0c;因此从…

python爬虫入门(实践)

python爬虫入门&#xff08;实践&#xff09; 一、对目标网站进行分析 二、博客爬取 获取博客所有h2标题的路由 确定目标&#xff0c;查看源码 代码实现 """ 获取博客所有h2标题的路由 """url "http://www.crazyant.net"import re…

nginx 配置代理,根据 不同的请求头进行转发至不同的代理

解决场景&#xff1a;下载发票的版式文件&#xff0c;第三方返回的是url链接地址&#xff0c;但是服务是部署在内网环境&#xff0c;无法访问互联网进行下载。此时需要进行走反向代理出去&#xff0c;如果按照已有套路&#xff0c;就是根据不同的访问前缀&#xff0c;跳转不同的…

EI Scopus双检索 | 2025年第四届信息与通信工程国际会议(JCICE 2025)

会议简介 Brief Introduction 2025年第四届信息与通信工程国际会议(JCICE 2025) 会议时间&#xff1a;2025年7月25日-27日 召开地点&#xff1a;中国哈尔滨 大会官网&#xff1a;www.jcice.org 由黑龙江大学和成都信息工程大学主办&#xff0c;江苏科技大学协办的2025年第四届信…

软考高级5个资格、中级常考4个资格简介及难易程度排序

一、软考高级5个资格 01、网络规划设计师 资格简介&#xff1a;网络规划设计师要求考生具备全面的网络规划、设计、部署和管理能力&#xff1b;该资格考试适合那些在网络规划和设计方面具有较好理论基础和较丰富从业经验的人员参加。 02、系统分析师 资格简介&#xff1a;系统分…

STM32 FreeRTOS 任务挂起和恢复---实验

实验目标 学会vTaskSuspend( )、vTaskResume( ) 任务挂起与恢复相关API函数使用&#xff1a; start_task:用来创建其他的三个任务。 task1&#xff1a;实现LED1每500ms闪烁一次。 task2&#xff1a;实现LED2每500ms闪烁一次。 task3&#xff1a;判断按键按下逻辑&#xff0c;KE…

YOLO系列代码

Test-Time Augmentation TTA (Test Time Augmentation)是指在test过程中进行数据增强。其思想非常简单&#xff0c;就是在评测阶段&#xff0c;给每个输入进行多种数据增广变换&#xff0c;将一个输入变成多个输入&#xff0c;然后再merge起来一起输出&#xff0c;形成一种ens…

《自动驾驶与机器人中的SLAM技术》ch4:基于预积分和图优化的 GINS

前言&#xff1a;预积分图优化的结构 1 预积分的图优化顶点 这里使用 《自动驾驶与机器人中的SLAM技术》ch4&#xff1a;预积分学 中提到的散装的形式来实现预积分的顶点部分&#xff0c;所以每个状态被分为位姿&#xff08;&#xff09;、速度、陀螺零偏、加计零偏四种顶点&am…

docker 部署confluence

1.安装docker的过程就不说了。 2.下载镜像。 docker pull cptactionhank/atlassian-confluence:7.4.0 docker images 3.下载pojie 包。 https://download.csdn.net/download/liudongyang123/90285042https://download.csdn.net/download/liudongyang123/90285042https://do…

前端实习第二个月小结

时间飞快&#xff0c;第一次实习已经过去两个多月&#xff0c;作一些简单的总结和分享。 注&#xff1a;文章整体会比较轻松&#xff0c;提及的经历、经验仅作参考。 一、关于实习/工作内容 1、工作内容 近期做的是管理后台方面的业务&#xff0c;技术栈&#xff1a;前端re…

搭建一个基于Spring Boot的书籍学习平台

搭建一个基于Spring Boot的书籍学习平台可以涵盖多个功能模块&#xff0c;例如用户管理、书籍管理、学习进度跟踪、笔记管理、评论和评分等。以下是一个简化的步骤指南&#xff0c;帮助你快速搭建一个基础的书籍学习平台。 — 1. 项目初始化 使用 Spring Initializr 生成一个…

dl学习笔记:(4)简单神经网络

&#xff08;1&#xff09;单层正向回归网络 bx1x2z100-0.2110-0.05101-0.051110.1 接下来我们用代码实现这组线性回归数据 import torch x torch.tensor([[1,0,0],[1,1,0],[1,0,1],[1,1,1]], dtype torch.float32) z torch.tensor([-0.2, -0.05, -0.05, 0.1]) w torch.…

OpenHarmony-7.IDL工具

IDL 工具 1.openharmony IDL工具 在OpenHarmony中&#xff0c;当应用/系统服务的客户端和服务端进行IPC&#xff08;Inter-Process Communication&#xff09;跨线程通信时&#xff0c;需要定义双方都认可的接口&#xff0c;以保障双方可以成功通信&#xff0c;OpenHarmony ID…