【6. 激光雷达接入ROS】

news2024/11/29 8:57:36

欢迎大家阅读2345VOR的博客【6. 激光雷达接入ROS】🥳🥳🥳
2345VOR鹏鹏主页: 已获得CSDN《嵌入式领域优质创作者》称号👻👻👻,座右铭:脚踏实地,仰望星空🛹🛹🛹
🎏🎏主要开发专栏🎏🎏
《arduino学习》:学习最简单开源便利的单片机Arduino,与时俱进😆😆😆
《Arduino编程参考》:本专栏围绕Arduino语法和Arduino库使用开发;🌻🌻🌻
《 Arduino小项目开发》:本专栏围绕Arduino生态结合实际需求设计综合的小项目开发。🌼🌼🌼
《HomeAssistant》:介绍homeassistant中基本开发, 重点设计esphome和nodered开发,包含小爱同学打印机等诸多设备添加。🎉🎉🎉
本文章属于《Ubuntu学习》和《ROS机器人学习》
:围绕Ubuntu系统基本配置及相关命令行学习记录!机器人操作系统 (ROS) 是一组软件库和工具,可帮助您构建机器人应用程序。👍👍👍

1. 前言

Ubuntu环境搭建
【经典Ubuntu20.04版本U盘安装双系统教程】
【Windows10安装或重装ubuntu18.04双系统教程】
【Ubuntu同步系统时间】
【Ubuntu中截图工具】
【Ubuntu安装QQ】
【Ubuntu安装后基本配置】
【Ubuntu启动菜单的默认项】
【ubuntu系统中修改hosts配置】
【18.04Ubuntu中解决无法识别显示屏】
ROS学习笔记
【1. Ubuntu18.04安装ROS Melodic】
【2. 在Github上寻找安装ROS软件包】
【3. 初学ROS,年轻人的第一个Node节点】
【4. ROS的主要通讯方式:Topic话题与Message消息】
【5. ROS机器人的运动控制】

接下来学习激光雷达如何接入ros机器人,激光雷达是用来探测周围障碍物的分布状况!
在这里插入图片描述

2. 激光雷达分类

其按照测量的维度可以分为单线雷达和多线雷达

在这里插入图片描述
按照测量原理分为三角测距雷达和TOF雷达

在这里插入图片描述
根据工作方式分为机械旋转雷达和固态雷达

在这里插入图片描述
激光雷达虽各有不同,但是在ROS中呈现的数据格式是一样的,只是在数据完整度和精度上会有所差异。下面就选取TOF激光雷达作为例子

3. TOF和三角测距激光雷达

3.1 何为飞行时间测距(TOF)?

简单来说,就是计算光的“飞行时间”。

在这里插入图片描述

由激光器发射一个激光脉冲,通过计时器记录下光的出射和回返的时间,两个时间相减即可得到光的“飞行时间”,而光速是固定的,根据已知速度和时间就可以计算出距离。

3.2 何为三角测距?

三角测距采用激光器发射激光,在照射到物体之后,反射光会由线性CCD接收,因为激光器和探测器间隔了一段距离,所以根据光学路径,不同距离的物体将会在CCD上成像在不同的位置,按照三角公式进行计算,就可以推导出被测物体的距离。
在这里插入图片描述

3.3 激光雷达测距

TOF激光雷达计算如下
在这里插入图片描述

在这里插入图片描述

4. 使用RViz观测传感器数据

RViz这个工具的全名叫做 The Robot Visualization Tool

在这里插入图片描述

4.1 运行模板样机

打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
rviz

首先把这个Fixed Frame修改成base_footprint

在这里插入图片描述
状态栏添加机器人模型,最后点击ok
在这里插入图片描述
选择激光雷达的话题名称/scan

在这里插入图片描述
调整size为0.03
在这里插入图片描述
调整RViz和Gazebo分屏

在这里插入图片描述
Gazebo是模拟真实机器人发出传感器数据的工具
RViz显示的是机器人实际能探测到的环境状况
在这里插入图片描述
在这里插入图片描述
另外一点就是RViz并不参与机器人算法的运行,它只是一个为了方便人类进行观测的工具而已
即使没有RViz,也不影响机器人的ROS系统的运行
只有需要观察某些数据实时变化的时候,才会打开RViz
下面添加虚拟环境的圆柱体障碍物
在这里插入图片描述

在这里插入图片描述

4.2 保存RViz配置

点击file菜单,选择Save Config As
在这里插入图片描述
选择保存地址,方便后期直接加载
在这里插入图片描述
然后关闭所有终端
打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
rviz

然后在RViz中的file菜单,选择Open Config
在这里插入图片描述
然后选择刚保存的位置

在这里插入图片描述

4.3 自动加载rviz配置文件

还可以在launch文件里自动加载rviz配置文件
先关闭RViz,然后打开终端输入

roslaunch wpr_simulation wpb_rviz.launch

在这里插入图片描述
关闭摄像头,保留激光雷达
在这里插入图片描述
调整视角
在这里插入图片描述

5. ROS系统中的激光雷达消息包格式

5.1 运行模板样机

打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
roslaunch wpr_simulation wpb_rviz.launch

在这里插入图片描述

在Gazebo中围绕机器人堆积障碍物
在这里插入图片描述

5.2 sensor_msgs中Laserscan_msgs消息属性

进入ROS Index官网搜索sensor_msgs
在这里插入图片描述

在这里插入图片描述
进入website
在这里插入图片描述
在消息中找到LaserScan
在这里插入图片描述
这就打开了激光雷达消息包的格式定义

在这里插入图片描述
在这里插入图片描述

5.3 查看scan消息

新开终端输入

rostopic echo /scan --noarr

在这里插入图片描述
显示对比

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6. 用C++获取ROS激光雷达数据节点

6.1 运行模板样机

采用wpr_simulation开源工程,打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
rosrunwpr_simulation deno_lidar_data


在这里插入图片描述

6.2 构思功能的思路和步骤

构思
在这里插入图片描述
实现步骤

  1. 构建一个新的软件包,包名叫做lidar_pkg。
  2. 在软件包中新建一个节点,节点名叫做lidar_node。
  3. 在节点中,向ROS大管家NodeHandle申请订阅话题/scan,并设置回调函数为LidarCallback()。
  4. 构建回调函数LidarCallback(),用来接收和处理雷达数据。
  5. 调用ROS_INFO()显示雷达检测到的前方障碍物距离。

6.3 创建lidar_pkg包

在工作空间src文件创建基于sensor_msgs模板的lidar_pkg

cd ~/catkin_ws/src/
catkin_create_pkg lidar_pkg roscpp rospy sensor_msgs

在这里插入图片描述
在lidar_pkg文件夹下src中创建lidar_node.cpp
在这里插入图片描述

在这里插入图片描述

6.4 编写订阅者节点

lidar_node源码

#include <ros/ ros.h>
#include <sensor msgs/Laserscan.h>
void Lidarcallback(const sensor_msgs::LaserScan msg)
{
	float fMidDist = msg.ranges[180] ;
	ROS_INFO("前方测距ranges [180]=%f 米", fMidDist);
}
int main(int argc,char *argv[])
{
	setlocale(LC_ALL, "" );
	ros::init(argc, argv,"lidar_node" );
	ros::NodeHandle n;
	ros::Subscriber lidar_sub = n.subscribe( " /scan", 10, &LidarCallback);
	ros::spin();
	return 0;
}


ctrl+s快捷保存

6.5 设置C++编译规则

打开CMake文件


add_executable(lidar_node src/lidar_node.cpp)
target_link_libraries(lidar_node
	${catkin_LIBRARIES}
)


ctrl+s快捷保存
在这里插入图片描述
ctrl+shift+b快捷编译

6.6 编译运行lidar_node节点

编译,打开终端

cd ~/catkin_ws/
catkin_make

采用wpr_simulation开源工程,打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun lidar_pkg lidar_node


在这里插入图片描述
前方距离2.6m,然后在Gazebo中调整书柜,选择移动靠近机器人
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可参照可以打开.wpr_simulation里的demo_lidar_data.cpp文件

在这里插入图片描述

7. 用python获取ROS激光雷达数据节点

7.1 运行模板样机

采用wpr_simulation开源工程,打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun wpr_simulation deno_lidar_data.py

在这里插入图片描述

7.2 构思功能的思路和步骤

构思
在这里插入图片描述
实现步骤

  1. 构建一个新的软件包,包名叫做lidar_pkg。
  2. 在软件包中新建一个节点,节点名叫做lidar_node.py。
  3. 在节点中,向ROS大管家rospy申请订阅话题/scan,并设置回调函数为LidarCallback()。
  4. 构建回调函数LidarCallback(),用来接收和处理雷达数据。
  5. 调用loginfo()显示雷达检测到的前方障碍物距离。

7.3 创建lidar_pkg包

在工作空间src文件创建基于sensor_msgs模板的lidar_pkg,编译

cd ~/catkin_ws/src/
catkin_create_pkg lidar_pkg roscpp rospy sensor_msgs
cd ..
catkin_make

在这里插入图片描述

在lidar_pkg文件夹下新建script文件夹中创建lidar_node.py
在这里插入图片描述

在这里插入图片描述

7.4 编写订阅者节点

先引入python包,设置中文utf-8显示

  • ros>=20.04,采用python3
  • ros<20.04,采用python

lidar_node.py源码

#!/usr/bin/env python3
#coding=utf-8
import rospy
from sensor_msgs.msg import LaserScan
def Lidarcallback(msg):
	dist = msg.ranges [ 180]
	rospy.loginfo("前方测距 ranges [ 180] = %f 米" , dist)
if _name ="_main_":
	rospy.init_node( "lidar_node" )
	lidar_sub = rospy.Subscriber( " /scan" ,LaserScan,Lidarcallback,queue_size=10)
	rospy.spin()

ctrl+s快捷保存

7.5 添加可执行的权限

在所在文件夹打开终端

cd catkin_ws/src/lidar_pkg/scripts/
ls
chmod +x lidar_node.py
ls

文件名变成绿色表示权限添加成功

在这里插入图片描述

7.6 运行lidar_node节点

采用wpr_simulation开源工程,打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun lidar_pkg lidar_node.py


在这里插入图片描述

前方距离2.6m,然后在Gazebo中调整书柜,选择移动靠近机器人
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可参照可以打开wpr_simulation里的script文件夹中创建lidar_node.py

在这里插入图片描述

8. 用C++编写激光雷达避障节点

在这里插入图片描述
基于前面学习的机器人运动控制和激光雷达数据,下面将联系这两点编写激光雷达避障节点

8.1 构思功能的思路和步骤

  1. 让大管家NodeHandle 发布速度控制话题/cmd_vel 。
  2. 构建速度控制消息包vel_cmd。
  3. 根据激光雷达的测距数值,实时调整机器人运动速度,避开障碍物。

8.2 修改lidar_node.cpp

在这里插入图片描述
见6.4源码
修改成如下lidar_node源码

#include <ros/ ros.h>
#include <sensor msgs/Laserscan.h>
#include <geometry msgs/Twist.h>
ros::Publisher vel_pub;

void Lidarcallback(const sensor_msgs::LaserScan msg)
{
	float fMidDist = msg.ranges[180] ;
	ROS_INFO("前方测距ranges [180]=%f 米", fMidDist);
	geometry msgs::Twist vel_cmd ;
	if( fMidDist< 1.5)
	{
		vel_cmd.angular.z = 0.3;
	}
	else
	{
		vel_cmd.linear.x = 0.05;
	}
	vel_pub.publish(vel_cmd);


}
int main(int argc,char *argv[])
{
	setlocale(LC_ALL, "" );
	ros::init(argc, argv,"lidar_node" );
	ros::NodeHandle n;
	ros::Subscriber lidar_sub = n.subscribe( " /scan", 10, &LidarCallback);
	ros::spin();
	return 0;
}


ctrl+s快捷保存

ctrl+shift+b快捷编译
在这里插入图片描述

8.4 运行lidar_node节点

采用wpr_simulation开源工程,打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun lidar_pkg lidar_node


在这里插入图片描述
机器人撞到障碍物,机器人有宽度

8.4 优化避障策略

当机器人检测前方障碍物时,最简单把转弯角度调大一点,原地转弯
lidar_node源码

#include <ros/ ros.h>
#include <sensor msgs/Laserscan.h>
#include <geometry msgs/Twist.h>
ros::Publisher vel_pub;
int ncount = 0;

void Lidarcallback(const sensor_msgs::LaserScan msg)
{
	float fMidDist = msg.ranges[180] ;
	ROS_INFO("前方测距ranges [180]=%f 米", fMidDist);
	if(ncount > 0)
	{
		ncount--;
		return;
	}

	
	geometry msgs::Twist vel_cmd ;
	if( fMidDist< 1.5)
	{
		vel_cmd.angular.z = 0.3;
		ncount = 50;
	}
	else
	{
		vel_cmd.linear.x = 0.05;
	}
	vel_pub.publish(vel_cmd);


}
int main(int argc,char *argv[])
{
	setlocale(LC_ALL, "" );
	ros::init(argc, argv,"lidar_node" );
	ros::NodeHandle n;
	ros::Subscriber lidar_sub = n.subscribe( " /scan", 10, &LidarCallback);
	ros::spin();
	return 0;
}


ctrl+s快捷保存

ctrl+shift+b快捷编译
然后在调试就OK啦
可参照开源项目wpr_simulation下的src文件夹的demo_lidar_behavior.cpp

在这里插入图片描述

9. 用python编写激光雷达避障节点

9.1 构思功能的思路和步骤

构思
在这里插入图片描述
实现步骤

  1. 让大管家rospy 发布速度控制话题/cmd_vel 。
  2. 构建速度控制消息包vel_cmd。
  3. 根据激光雷达的测距数值,实时调整机器人运动速度,避开障
    碍物。

9.2 修改lidar_node.py

打开7.4编写lidar_node.py
在这里插入图片描述

lidar_node.py源码

#!/usr/bin/env python3
#coding=utf-8
import rospy
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist

count =0

def Lidarcallback(msg):
	global vel_pub
	global count
	dist = msg.ranges [ 180]
	rospy.loginfo("前方测距 ranges [ 180] = %f 米" , dist)
	
	if count > 0:
		count = count - 1
		return
	
	vel_cmd = Twist()
	if dist< 1.5:
		vel_cmd .angular.z = 0.3
	else:
		vel_cmd.linear.x = 0.05
	vel_pub.publish(vel_cmd)

	
if _name ="_main_":
	rospy.init_node( "lidar_node" )
	lidar_sub = rospy.Subscriber( " /scan" ,LaserScan,Lidarcallback,queue_size=10)
	vel_pub = rospy.Publisher( " /cmd_vel" ,Twist , queue_size=10)
	rospy.spin()

ctrl+s快捷保存

6.6 运行lidar_node节点

采用wpr_simulation开源工程,打开三个终端分别运行三条指令

roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun lidar_pkg lidar_node.py


在这里插入图片描述
可参照可以打开wpr_simulation里的script文件夹中demo_lidar_behavior.py
在这里插入图片描述

10. 总结

本节学习了ROS机器人的激光雷达原理和数据查看,尝试C++和python两种语言编写,并且结合前面的机器人运动编写了避障节点,接下来会介绍机器人的IMU传感器的操作。🎉🎉🎉

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Go | 一分钟掌握Go | 8 - 并发

作者&#xff1a;Mars酱 声明&#xff1a;本文章由Mars酱编写&#xff0c;部分内容来源于网络&#xff0c;如有疑问请联系本人。 转载&#xff1a;欢迎转载&#xff0c;转载前先请联系我&#xff01; 前言 当今编程界&#xff0c;一个好的编译型语言如果不支持并发&#xff0c…

工控老司机告诉你热电偶和RTD的区别

热电偶和热电阻都是温度传感器&#xff0c;但它们的原理、功能特性和应用场景有所不同。 一、原理区别 首先&#xff0c;热电偶是利用两种不同金属之间的热电效应来测量温度的。其原理是利用温度差引起的金属之间的热电势差进行测量。两种金属之间存在一种热电势&#xff08;…

Yolov8优化:卷积变体---分布移位卷积(DSConv),提高卷积层的内存效率和速度

论文: https://arxiv.org/pdf/1901.01928v1.pdf 摘要:提出了一种卷积的变体,称为DSConv(分布偏移卷积),其可以容易地替换进标准神经网络体系结构并且实现较低的存储器使用和较高的计算速度。 DSConv将传统的卷积内核分解为两个组件:可变量化内核(VQK)和分布偏移。 通过…

双亲委派机制的原理和作用

双亲委派机制&#xff0c;就必须弄清楚Java的类加载器。 什么是类加载器 Java类加载器(ClassLoader)是Java运行时环境(JRE)的一部分&#xff0c;负责动态的将Java类加载到Java虚拟机的内存空间。 类加载器有哪些 主要有三个&#xff1a; 引导类加载器(Bootstrap ClassLoade…

前端开发在本地开发与后台进行联调阶段时,接口自动重定向https、HSTS 与 307 状态码

开发者在本地开发与后台进行联调阶段时&#xff0c;Chrome 浏览器上出现 307 状态码&#xff0c;并跳转到 https 版 但是 307 代码是什么含义呢&#xff1f;页面又为何会出现 307 状态码呢&#xff1f;我之前都没见过这个状态码&#xff0c;查了才知道原来它也是一种重定向。 …

数字三角形+包子凑数(蓝桥杯JAVA解法)

数字三角形&#xff1a;用户登录 题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径&#xff0c;把路径上面的数加起来可以得到一个和&#xff0c;你的任务就是找到最大的和&#xff08;路径上的每一步只可沿左斜线向下或右斜线向下走…

ArduPilot之开源代码Sensor Drivers设计

ArduPilot之开源代码Sensor Drivers设计 1. 源由2. Sensor Drivers设计2.1 front-end / back-end分层2.2 设计思想分析 3 实例理解3.1 驱动初始化3.2 业务应用代码3.3 frond-end代码3.3 back-end代码3.3.1 UART3.3.2 I2C3.3.3 SPI 4. 参考资料 1. 源由 飞控代码除了最为基础的…

《美团机器学习实践》读后感和一点思考

前言&#xff1a;最近拜读了美团算法团队出品的《美团机器学习实践》&#xff0c;这本书写于2018年&#xff0c;一个大模型还没有标配的时代。这本书侧重于工业界的实践&#xff0c;能清楚地让我们了解到工业界和学术界对机器学习的关注方向上的差异&#xff0c;值得一读。因为…

文件系统和软硬链接

文章目录 一.文件系统1.了解磁盘的物理结构2.磁盘的存储结构a.磁盘读取 3.磁盘的逻辑结构a.为什么操作系统不直接使用CHS地址&#xff1f;b.实际IO一次的大小 4.磁盘的分区管理4.1.ext文件系统a.文件查找b.文件删除 4.2目录的属性和数据 二.软硬链接软链接的建立和删除软链接的…

【VM服务管家】VM4.0软件使用_1.4 通讯类

目录 1.4.1 通讯管理&#xff1a;ModBus通信发送非整型数据的方法1.4.2 通讯管理&#xff1a;使用Modbus TCP通讯协议与流程交互 1.4.1 通讯管理&#xff1a;ModBus通信发送非整型数据的方法 描述 环境&#xff1a;VM4.0.0 现象&#xff1a;Modbus通信发送数据只能为Int类型&a…

快速搭建Electron+Vite3+Vue3+TypeScript5脚手架 (无需梯子,快速安装Electron)

一、介绍 &#x1f606; &#x1f601; &#x1f609; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需…

【网课平台】Day13.订单支付模式:生成支付二维码与查询支付

文章目录 一、需求&#xff1a;生成支付二维码1、需求分析2、表设计3、接口定义4、接口实现5、完善controller 二、需求&#xff1a;查询支付结果1、需求分析2、表设计与模型类3、接口定义4、接口实现步骤一&#xff1a;查询支付结果步骤二&#xff1a;保存支付结果&#xff08…

如何写出一份大厂都不会拒绝的简历?

你好&#xff0c;我是宋光璠&#xff0c;今天我以过来人的身份教你写出一份惊艳面试官的简历。 简历算是我们过去经历的一个缩影&#xff0c;虽然只有短短一两页&#xff0c;但也能让人从中发现你的优点&#xff0c;一份优质的简历更是如此&#xff0c;所以今天我就带你从头到…

PLC模糊PID(梯形图实现)

博途PLC的模糊PID控制详细内容请查看下面的博客文章: Matlab仿真+博途PLC模糊PID控制完整SCL源代码参考(带模糊和普通PID切换功能)_博途怎么实现模糊pid_RXXW_Dor的博客-CSDN博客模糊PID的其它相关数学基础,理论知识大家可以参看专栏的其它文章,这里不再赘述,本文就双容…

网络安全常用术语

肉鸡 肉鸡指的就是被黑客成功入侵并取得控制权限的电脑。黑客们可以随意的控制肉鸡&#xff0c;就像在使用自己的电脑一样&#xff0c;很形象的比喻&#xff0c;就像是养的肉鸡&#xff0c;任黑客宰杀和利用。关键的是&#xff0c;在成为肉鸡后&#xff0c;只要黑客不对电脑进…

【VM服务管家】VM4.x算子SDK开发_3.4 控件嵌入类

目录 3.4.1 图片存储&#xff1a;图片保存的方法3.4.2 辅助十字线&#xff1a;给图像添加辅助十字线的方法3.4.3 控件调用&#xff1a;在WPF中使用Winform控件的方法3.4.4 图形改变事件&#xff1a;渲染控件上图形改变事件的实现方法3.4.5 鼠标事件&#xff1a;渲染控件上鼠标事…

Hive的基本操作和查询语法以及案例(大数据查询)

1、 13-Hive的基本操作和查询语法以及案例_hive分区表查询语句_大数据下的画像人的博客-CSDN博客 2、SQL 中多个 and or 的组合运算 SQL 中多个 and or 的组合运算_weixin_30611509的博客-CSDN博客sql关系型运算符优先级高到低为&#xff1a;not >and> orAND、OR运算符…

零基础想成为黑客,只需要四步

前言 首先要明白&#xff0c;该篇文章说的黑客不是那种窃取别人信息、攻击别人系统的黑客&#xff0c;说的是调试和分析计算机安全系统的网络安全工程师。 黑客技术的核心之一就是渗透攻防技术&#xff0c;是为了证明网络防御按照预期计划正常运行而提供的一种机制。就是通过模…

语音处理加窗分帧

语音处理加窗分帧 一、分帧 语音数据和视频数据不同&#xff0c;本没有帧的概念&#xff0c;但是为了传输与存储&#xff0c;我们采集的音频数据都是一段一段 的。为了程序能够进行批量处理&#xff0c;会根据指定的长度(时间段或者采样数)进行分段&#xff0c;结构化为我们编程…

从FPGA说起的深度学习(八)-数据并行性

这是新的系列教程&#xff0c;在本教程中&#xff0c;我们将介绍使用 FPGA 实现深度学习的技术&#xff0c;深度学习是近年来人工智能领域的热门话题。 在本教程中&#xff0c;旨在加深对深度学习和 FPGA 的理解。 用 C/C 编写深度学习推理代码高级综合 (HLS) 将 C/C 代码转换为…