导语
今天继续康奈尔大学FPGA 课程ECE 5760的典型案例分享——基于FPGA加速的bird-oid object算法实现。
(更多其他案例请参考网站:
Final Projects ECE 5760)
1. 项目概述
项目网址
ECE 5760 Final Project
模型说明
Bird-oid object 简称Boids模型,是美国的一个图形计算机科学家Craig Reynolds在 1986 年开发出来的。
他的Boids模型为集群个体抽象出三个基本行为:分离(seperation)、对齐(alignment)、与聚集(cohesion)。将这三种行为按一定权重进行混合,可以让群体出现秩序化的社会性行为。这个模型自从提出到现在一直持续影响着社会学、生物学、计算机科学等学科的发展。基于这个模型的应用其实很多, 比如现在的集群无人地面车辆,集群无人机灯光秀等等。
项目说明
本项目使用DE1 SoC的ARM A9处理器和FPGA逻辑的组合,不仅成功地模拟了动态boid (bird-oid object)群集模式,而且还优化了周期要求和执行时间。
本项目首先创建了一个完全运行在ARM A9处理器上的“基线”设计。这个基线设计是使用C代码创建的,能够以每秒60帧的速度计算最多3,000个对象的群集模式。
我们的第二个对比设计是在FPGA上创建一个更新功能可以计算和更新每个物体在x和y坐标上的位置,以及它们在x和y方向上的速度。最后成功地在FPGA上模拟了最多显示150个对象的boids群集模式。
这个项目的目标是改善更新功能所需的周期数,并看到总体执行时间的改进。如果能够减少运行更新的专用硬件的循环次数,估计就最终可以在ARM处理器上进行超过3000个对象的计算。
2. 实现原理
要创建boids群集模拟,需要遵循三个主要步骤:分离、对齐和聚集。
-
分离 Separation:离得太近的物体会相互远离
-
对齐 Alignment:对齐是指每个物体试图匹配其可见范围内物体的速度,朝着周围同伴的平均方向前进
-
聚集 Cohesion:朝着周围同伴的平均位置移动
当对象之间靠得太近时,执行两个步骤使对象之间稍微散开一点。第一步是计算当前节点到最近节点的距离:
close_dx += boid.x - otherboid.x
close_dy += boid.y - otherboid.y
一旦这被计算出来,我们就创造了一个回避因素:avoidfactor。这个avoidfactor虽然仍然相对较小,但将乘以之前计算的close_dx和close_dy值:
boid.vx += close_dx*avoidfactor
boid.vy += close_dy*avoidfactor
下一步是对齐所需的计算。我们执行以下步骤:
-
在开始更新特定对象时,三个变量(xvel_avg、yvel_avg和neighboring_boids)为零。
-
循环遍历每一个其他的对象。如果到特定对象的距离小于可见范围,则
xvel_avg += otherboid.vx
yvel_avg += otherboid.vy
neighboring_boids += 1
循环遍历所有其他物体后,如果neighboring_boids > 0,则执行以下操作:
xvel_avg = xvel_avg/neighboring_boids
yvel_avg = yvel_avg/neighboring_boids
然后根据以下公式更新速度:
boid.vx += (xvel_avg - boid.vx)*matchingfactor
boid.vy += (yvel_avg - boid.vy)*matchingfactor
(其中matchingfactor是一个可调参数)
最后一次物体对物体的更新是基于聚集性,因为每个物体对象都在其可见范围内缓慢地转向其他对象的质心。它是这样做的:
1. 在开始更新特定对象时,三个变量(xpos_avg、ypos_avg和neighboring_boids)为零
2. 循环遍历每一个其他的对象。如果到特定对象的距离小于可见范围,则
xpos_avg += otherboid.x
ypos_avg += otherboid.y
neighboring_boids += 1
循环遍历所有其他对象后,如果neighboring_boids > 0,则执行以下操作:
xpos_avg = xpos_avg/neighboring_boids
ypos_avg = ypos_avg/neighboring_boids
然后根据以下公式更新速度:
boid.vx += (xpos_avg - boid.x)*centeringfactor
boid.vy += (ypos_avg - boid.y)*centeringfactor
(其中centeringfactor是一个可调参数)
对象更新的最后一步是确定对象何时需要转动,以便所有对象都保持在正在使用的VGA屏幕的范围内。这可以通过下面的条件语句来实现:
if boid.x < leftmargin:
boid.vx = boid.vx + turnfactor
if boid.x > rightmargin:
boid.vx = boid.vx - turnfactor
if boid.y > bottommargin:
boid.vy = boid.vy - turnfactor
if boid.y < topmargin:
boid.vy = boid.vy + turnfactor
当使用不同的微控制器和显示器时,边界条件和背后的逻辑保持不变。
3. 视频演示
视频参考:基于FPGA加速的bird-oid object算法实现
4. 源码下载
-
ECE 5760 Final Project