×

使用PYNQ和Vitis AI的智能办公室热办公桌

消耗积分:0 | 格式:zip | 大小:0.03 MB | 2023-06-29

33391

分享资料个

描述

介绍

在这个项目中,我将为 Smart Office Hot Desking 安排创建一个应用程序。

  • 现代办公室正在采用“Hot Desking”的概念。以“先到先得”的方式更有效地利用共享空间和办公桌。然而,面临的问题是工人可能会浪费更多时间来寻找空置的办公桌。跟踪入住率并在预订系统中更新也很乏味。借助基于边缘的图像处理能力,我们可以检测区域内的人员并确定办公桌是否被占用。

在技​​术方面,我将使用 Ultra96-V2 演示 Vitis AI Model Zoo 和 PYNQ 的 DPU IP 内核的编译流程。

我将从头开始编译。从头开始编译将使以后修改硬件设计更容易。我觉得获取环境设置的过程令人困惑,因此我将帮助您逐步记录它。

PYNQ & Vitis AI 工作流程说明

在我们开始之前,重要的是要知道 Ultra96-V2 使用 Xilinx Zynq UltraScale+™ MPSoC。我们可以称它为基于 ARM 的 FPGA,这意味着既有处理系统(PS)又有可编程逻辑(PL)。

我将使用 PYNQ,我们在其中制作在 PS 上运行的 Python 脚本。使用预编译的 PYNQ 覆盖(或比特流),在 PL 中配置深度学习处理器单元 (DPU)。在 PS 上运行的软件可以使用 DPU 来加速图像识别任务。

使用的额外硬件

除了 Ultra96-V2 捆绑包之外,您可能还需要这些附加硬件。

1. USB 摄像头

  • 我使用了罗技 C170 USB 相机。
  • 通常,大多数罗技网络摄像头都应该开箱即用。其他带有 Linux 驱动程序的品牌也应该可以使用。

2. 有源 Mini-DisplayPort 适配器

  • 我使用了 PowerColor Active Mini Displayport 到单链路 DVI 适配器
  • Ultra96-V2 仅输出纯 DisplayPort 信号,因此需要有源适配器。
  • 为了获得更好的搜索结果,您可以尝试搜索“兼容 ATI Eyefinity”的适配器。众所周知,Eyefinity 适配器处于活动状态。
注意:如果您的预算有限,则可以不使用这些。例如,可以改用 IP 摄像机。有一些应用程序可以将您的智能手机用作 IP 摄像机。如果您使用 USB 或远程 SSH 进行连接,则可能不需要 mini-DP 适配器。
 
 
 
poYBAGN3LQOAJiUZAAHQMk_6g4c652.jpg
 
1 / 2罗技 C170 USB 摄像头
 

准备 PYNQ 映像

我们将首先将 PYNQ 加载到板上并进行一些测试。从官网下载Avnet Ultra96-V2 v2.5 PYNQ镜像。

您可以在社区板下找到它。

pYYBAGN3LQWAFo1vAABJUe4XPzI440.png
 

根据这些说明将图像写入 SD 卡。

插入你的 SD 卡。在 Ubuntu 上,您将能够在Disks应用程序中看到您的开发板。在这种情况下,设备名称是/dev/sdb

poYBAGN3LQiAD_BOAABMlBfg6zA509.png
 

卸载分区

$ umount /dev/sdb

下一个命令的设备名称要非常小心,我们将用 PYNQ 映像覆盖 SD 卡的内容。

您可以使用dd命令将 PYNQ 映像写入 SD 卡。我决定使用显示进度的dcfldd

$ sudo dcfldd bs=4M if=ultra96v2_v2.5.img of=/dev/sdb
1536 blocks (6144Mb) written.
1574+1 records in
1574+1 records out

启动 PYNQ

插入 SD 卡并按下电源按钮启动板。

poYBAGN3LQuAJXFeAAIZn3ow1f8621.png
 

将 Micro USB 电缆从您的 PC 连接到 Ultra96-V2。您将在 PC 上看到一个新的以太网接口。

您现在可以通过此链接在浏览器中访问 Jupyter Notebook http://192.168.2.1:9090

如果升级为密码,则为“xilinx”。

poYBAGN3LQ2APBFLAAAO8YdTUjo925.png
 

连接到 WiFi

我们需要将开发板连接到 Wifi,因为我们将下载一些东西。如果您有 USB 转以太网适配器,您也可以使用它并跳过本节。

有一个带有脚本的 Jupyter Notebook 可以帮助您连接到 Wifi。导航到notebooks/common/wifi.ipynb,您可以从这里将脚本修改为您自己的 Wifi 凭据。

pYYBAGN3LRGAWnYAAAFSmoF4OYY591.png
 

或者,如果您熟悉 Linux 系统,也可以发出以下命令

# Scan Wifi
$ ifconfig wlan0 up
$ iwlist wlan0 scan

# Connect to WEP access point
$ iwconfig wlan0 essid "YOUR_SSID_NAME" key s:YOUR_PASSWORD

# Connect to WPA access point
$ wpa_passphrase YOUR_SSID_NAME YOUR_PASSWORD > /etc/wpa_supplicant.conf
$ sudo wpa_supplicant -c /etc/wpa_supplicant.conf -i wlan0 -B

从这里我们可以从 Web 界面打开一个新终端。

poYBAGN3LRSASQWrAABUd7Ew7pk896.png
 

使用 Vitis AI 升级到最新的 PYNQ

在接下来的步骤中,我们将在终端中发出一些命令来下载和安装大量的包。估计需要1小时。

我建议安装 USB 风扇或任何冷却装置,因为 Ultra96-V2 会变得非常烫手。当它变热时,处理器将开始热调节并减慢进程。

 
 
 
pYYBAGN3LRmAZD8fAAGBeDX8RNI657.jpg
 
1 / 2
 

从 Jupyter Notebooks 打开终端。

从 Github 存储库下载并编译 Vitis AI PYNQ DPU。这是使用 Vitis-AI 升级 PYNQ 的步骤(可能需要大约一个小时才能完成):

$ git clone --recursive --shallow-submodules https://github.com/Xilinx/DPU-PYNQ.git
$ cd DPU-PYNQ/upgrade
$ make

安装pynq-dpu python包

pip3 install pynq-dpu

将 pynq-dpu 笔记本下载到您的主文件夹中

cd $PYNQ_JUPYTER_NOTEBOOKS
pynq get-notebooks pynq-dpu -p .

测试 USB 网络摄像头功能

连接您的 USB 网络摄像头并测试功能。

poYBAGN3LQOAJiUZAAHQMk_6g4c652.jpg
 

这里我使用的是 Logitech C170,它是由 PYNQ 自动检测到的。您可以使用此命令确认这一点。

$ lsusb
Bus 001 Device 004: ID 046d:082b Logitech, Inc. Webcam C170

在 Jupyter 中,打开位于./notebooks/common/usb_webcam.ipynb 的笔记本,您可以运行它来查看您的网络摄像头是否正常工作。

pYYBAGN3LR6AYL6JAAEK5LzOhB0194.png
 

现在我们已经验证了该板功能齐全。现在我们可以编译来自 Vitis AI Zoo 的 PYNQ DPU 图像和模型。

准备编译环境

我们需要安装 Xilinx Vitis 和 Xilinx Runtime (XRT) 版本 2020.1。对于 Vitis 和 XRT 2020.1,支持的最新操作系统是 Ubuntu 18.04.2 LTS。

不支持 Ubuntu 20.04,我无法成功安装。因此,我在虚拟机中安装了所有东西。

poYBAGN3LSKAY9rgAAEZ6dXi-WY072.png
虚拟机上的 Ubuntu 18.04.02 LTS
 

在此链接下载 Xilinx 运行时 (XRT) 的 .deb 文件

pYYBAGN3LSSAH6nXAAARwqMpHF4516.png
 

使用此命令安装它。

sudo apt install ./xrt_202010.2.6.655_18.04-amd64-xrt.deb

接下来,下载将安装 Vitis 2020.1 的 Xilinx Unified Web 安装程序。您需要注册一个 Xilinx 帐户。按照本网站上的说明进行操作

https://www.xilinx.com/html_docs/xilinx2020_1/vitis_​​doc/juk1557377661419.html

将您的 swappiness 设置为较低的值也很有用,因为构建过程使用大量 RAM。它告诉操作系统在换出到硬盘之前使用更多的 RAM。

要更改系统 swappiness 值,请以 root 身份打开 /etc/sysctl.conf

sudo gedit /etc/sysctl.con

然后,通过添加此行来更改 swappiness。我选择使用值 1。这意味着系统将使用多达 99% 的 RAM(剩余 1%),然后再将其交换到硬盘。

poYBAGN3LSmAZ18aAACkbDEYR5c576.png
 

应用更改。

sudo sysctl -p
pYYBAGN3LSuADOI1AAA11LRwIiM164.png
 

现在我们准备编译...

为 Ultra96-V2 编译 DPU-PYNQ

我们将密切参考本指南:

首先,从 Xilinx DPU-PYNQ 存储库中克隆构建文件

git clone --recursive --shallow-submodules https://github.com/Xilinx/DPU-PYNQ.git
cd DPU-PYNQ/boards

我们必须对构建文件进行一些更改,因为最初是在 Vitis 2019.2 中设计的,但现在我们正在使用更新的版本进行编译。

boards文件夹中,编辑check_env.sh

poYBAGN3LS6ATSkUAAAvJIXbkrc693.png
 

搜索2019.2,改成2020.1

poYBAGN3LTCAIhwcAAA2fcD-Gzw382.png
 

也去/vitis-ai-git/DPU-TRD/dpu_ip/dpu_eu_v3_2_0编辑component.xml

poYBAGN3LTKAWL8wAAA8GOm5WNo445.png
 

搜索2019.2,改成2020.1

pYYBAGN3LTaAOwjtAADZqMVRcgA674.png
 

最后,如果您想对 DPU IP 配置进行任何更改,请转到boards/Ultra96/dpu_conf.vh就我而言,我将内存更改为 RAM_USAGE_HIGH。

pYYBAGN3LTmAfCCLAABeTrtYcVY384.png
 

我们准备开始编译!

打开终端并获取 Xilinx 工具

source /opt/Xilinx/Vitis/2020.1/settings64.sh
source /opt/xilinx/xrt/setup.sh

开始编译(注:Ultra96和Ultra96-V2使用相同)

$ make BOARD=Ultra96

一段时间后,构建将再次失败,因为它检查的是版本2019.2而不是2020.1.

DPU-PYNQ/boards目录中查找。这是因为有一个名为 的新文件夹PYNQ-derivative-overlays构建脚本克隆了另一个名为PYNQ-derivative-overlays. 它负责将 DPU IP 置于 PYNQ 基础覆盖之上。

转到PYNQ-derivative-overlays/dpu/并编辑dpu.tcl

poYBAGN3LTuAQYjtAAA6Sa1O90g157.png
 

再次从 2019.2 更改为 2020.1

pYYBAGN3LT6AT-JlAACmUK0JrgA692.png
 

然后继续制作过程。

$ make BOARD=Ultra96
pYYBAGN3LUGAVzCGAAB1Y8wQAYw623.png
合成过程最长,可能需要一个小时
 

完成后,您将看到以下文件。这些文件是 PYNQ 的比特流覆盖。

poYBAGN3LUOAG8p_AABMCcnCH4g741.png
 

我会将这些文件上传到 Juypyter 实例中的一个名为 mymodel 的文件夹中。

在右上角,单击新建 > 文件夹

pYYBAGN3LUaAWpj6AAAbmCOpwgo728.png
 

然后在文件夹中,单击上传并选择 3 个文件。

poYBAGN3LUiALriHAABeZlumesU168.png
 

从 Vitis Model Zoo 编译 YoloV3

请注意:模型特定于您编译的 DPU(即,一种 DPU 配置的模型与另一种不兼容)。例如,这意味着如果您更改编译时使用的内核数量,您还必须重新编译模型。

准备 docker 文件

cd DPU-PYNQ/host
mkdir -p docker
cp -rf ../vitis-ai-git/docker_run.sh .
cp -rf ../vitis-ai-git/docker/PROMPT.txt docker
chmod u+x docker_run.sh

安装泊坞窗

sudo apt install docker -y
sudo groupadd docker
newgrp docker

运行 docker 实例

./docker_run.sh xilinx/vitis-ai-cpu:latest
pYYBAGN3LUqAKGPIAADVUbukWLY145.png
 

进入实例后,您可以编译模型

cp ../boards/Ultra96/dpu.hwh ./
./compile.sh Ultra96 tf_yolov3_voc_416_416_65.63G_1.1
poYBAGN3LU-AfPAPAABtXCieLI4875.png
 

完成后,您将在目录中看到模型,dpu_tf_yolov3.elf.

poYBAGN3LVGAd1tCAABfvZ2_FvE626.png
 

也将其上传到您的 Jupyter 实例。

poYBAGN3LVaAAfuxAAAw5dZx2yM493.png
 

示例笔记本

pynq_dpu/dpu_yolo_v3.ipynb有一个示例,它将测试 YoloV3 模型

现在制作一个副本(File > Make a Copy)并修改代码以指向包含我们自己编译的比特流和模型的mymodel文件夹

pYYBAGN3LVmAZTogAABH6-8roL0805.png
 

运行所有单元格(单元格 > 运行全部)

pYYBAGN3LVyAM79jAABgcHwCYvk902.png
 

验证图像分类成功

poYBAGN3LV-Aa-oPAADALEFfn3U891.png
 

哇,我们终于准备好申请了!

申请代码

最后,在所有硬件设置和测试后,我编写了软件来创建我自己的Smart Office Hot Desking 应用程序。第二个将利用数据显示基于座位可用性的仪表板。这是我第一次使用 Xilinx 硬件了解边缘上的 FPGA 和 AI。因此,刚开始时,我在开发工具和习惯环境方面遇到了最大的困难,因此,我尽我所能详细展示了设置过程。感谢您一直阅读到最后!


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.lene-v.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'使用PYNQ和Vitis AI的智能办公室热办公桌',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.lene-v.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);