1.AGV小车
1.1 串口通讯与色带导航算法
1.1.1 三个串口:
上位机与下位机运动控制串口,两个激光传感器串口
RS232,485串口速率要设置波特率,115200,设置校验位等信息,打开设备(open函数),是否有奇偶校验位
1.1.2 串口实质:
是文件,要想读写串口数据,必须先打开串口,设置串口,然后读写,读写完毕还要关闭串口。
1.1.3 色带导航算法思想:
保存当前传感器的位置信息和上一次前后传感器的位置信息。每次读取信息都要做均值处理,读取三帧数据,取报文中有效数据的均值。
1 | //前后传感器报文接收帧 |
函数:根据指定的位姿产生指令报文。
对前后数据进行判断,如果前后都没有色带,就原地旋转,
检测到色带后:
前有后无,就直行,然后不断读取当前传感器数据,判断状态并向standard调整(平行,左偏,右偏)
前无后有,就旋转到前有,然后跳出旋转
当前后都有,先直行一小段距离,然后判断状态并向标准调整。(直行,右平移,左平移,右旋转,左旋转)。
1.2 hectorSLAM
1.2.1激光雷达数据获取:
进行激光雷达数据结构的解析,采用Socket通讯,通过ROS进行打包发布。
1.2.2基于GN算法计算激光雷达位姿:
采用占据栅格地图,通过双线性差值,将激光雷达扫描数据投影到栅格地图中,然后引入GN算法,计算激光雷达位姿。对连续两帧激光数据进行匹配,估计算出移动机器人相对位姿的变化,然后通过连续叠加位姿变化从而实现对移动机器人的位姿跟踪,实现激光雷达自身定位。
1.2.3 全局位姿优化与环境地图绘制:
需要利用图优化的思想,根据约束建模,增量参数化和误差函数设计实现最小化误差,实现位姿优化。最后构建出环境占据栅格地图。进行全局位姿优化的目的是为了降低位姿计算过程伴随的误差问题。首先对激光数据进行直线拟合,在此基础上提取角点特征,完成角点检测过程。以角点作为路标,结合机器人位姿构建出图模型,从而将SLAM问题转换成图优化问题。通过约束建模,增量参数化以及误差函数设计三个步骤实现最小化误差的目的,实现位姿优化,然后构建出环境占据栅格地图,实现了完整的SLAM设计流程。
1.2.4 角点检测算法:
提出并实现一种基于最小二乘法直线拟合的角点检测算法。主要包括了角点特征滤波,特征值计算和NMS(非极大值抑制)处理。
难点:
1.串口通信
2.算法设计:色带导航算法,角点检测算法;
3.代码研究。不断的剥离代码,做注释。
2.视频压缩算法:
gropf指令可以看到程序中每个函数的消耗时间。
2.1采用SSE指令+loop unrolling对视频压缩进行优化。其中包括sad_block,dct优化。
2.2对压缩算法的运动估计的参数进行调整。
比如cm->me_search_range,参数越小,压缩时间越快,相当于搜索范围越小,但这个参数越小,编码文件的size就会越大。
对量化的精度参数进行调整。编码文件的大小在缩小,PSNR的数值在减小,但同样的执行时间也在减小,这里执行时间减小可能是因为编码文件大小改变引起的。根据实际播放效果来看,当cm->qp=10的时候播放是可以接受的,Y分量上的PSNR有34.5,U分量和V分量有40左右。当cm->qp=5的时候,播放出现了麻点,有点老式电视机播放的样子,但基本清晰,也勉强可以接受,但由于编码时间减少不多,PSNR降的却很多,因此不建议将参数设置为5,参数值设置为10是比较合适的。保证了较高的压缩比和编码速率,同时保证了视频的质量。
2.3采用cuda架构进行GPU视频编码。
2.3.1cuda的线程模型
Host(主机端)执行核函数 Kernel,而 Device(GPU)上运行 Grid,每一个 Grid 上面包含了很多的 block,而每个 block 上又包含了很多的线程,并且他们都可以被定义为一维、二维和三维的方式,在每个 block 内部又可以进行线程之间的同步和数据共享。
当 Host 端需要进行大量并行计算的时候,会将数据从内存传入到 GPU 中,然后GPU 再利用自身高并发的特性,完成并行计算,计算完成之后再将计算结果传回到 CPU。
2.3.2sad_block优化
将两个 block 块放入到 GPU 中,再利用核函数完成对应像素点的差值计算,最后将每个像素的差值返回到 CPU 中,完成求和计算,就得到了这两个块的 SAD 计算 。但CPU到GPU频繁的交换导致优化适得其反。
2.3.3运动估计优化
将一帧图像完全送入到 GPU 中进行处理。将一帧的图像分成很多的 macroblock(宏块),在编码器中一个宏块的大小是 8x8 的矩阵,里面存储了 64 个像素。我的想法是一个 grid 中分割成(weight/8)(height8)个 block,其中 weight 和 height 是该帧图像的宽和高。在每个block 中根据 YUV 分量的不同操作,拥有不同的线程数,这个线程数主要取决于他们的搜索范围不同,比如对于 Y 分量,搜索范围就是 3232,所以会有 1024 个线程,每个线程中将两个对应的 88 的宏块进行差值计算,并且在一个 block 中找到最优的 SAD即最小的),因此在实际设计中,需要设置一个shared的变量 best_sad,让块中的每个线程都可以共享访问,确定自己对应的这个宏块是不是当前确定运动估计的最佳匹配块。