乐动ld06激光雷达sdk改bug记录分享

简介: 乐动ld06激光雷达sdk改bug记录分享

前言:

工作中,有使用过乐动ld06款激光雷达,此款雷达将常规雷达的转动的电机部分内置于自己的保护罩内,减少了雷达本身转动积灰等其他外界影响,探测半径是12m,是一款不错的雷达。

不过今天的主要内容不是介绍该雷达的性能,而是分享我在使用该雷达过程中,在进行项目开发中,发现一个在官方SDK中隐藏的问题,这个问题,在使用过程中,导致了进程的崩溃。

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
[laser-2] process has died [pid 2323, exit code -6]

作者:良知犹存

转载授权以及围观:欢迎关注微信公众号羽林君

或者添加作者个人微信:become_me


ld06介绍:839886cd3c004deb9abdba851aa48a4c.png

LD06 主要由激光测距核心,无线传电单元,无线通讯单元,角度测量单元、电机驱动单元和机械外壳组成。

LD06 测距核心采用 DTOF 技术,可进行每秒 4500 次的测距。每次测距时,LD06 朝前发

射出红外激光,激光遇到目标物体后被反射到单光子接收单元。由此,我们获取到了激光的发

出时间和单光子接收单元收到激光的时间,两者的时间差即光的飞行时间,飞行时间再结合光

速即可解算出距离。

情况介绍:

最近使用乐动雷达时候,进行了一个上电下电读取数据的疲劳测试,经过脚本频繁的执行后,代码出现了崩溃。

最后面检查发现是一处浮点计算转换导致内存分配溢出的问题,而问题出现部分是官方包的计算没有做一些数据健壮的判断,最终导致了崩溃。

上面是代码原理,而从使用场景分析的话,出现这个问题的原因是,我们在进行机器断电再次上电时候,激光发生器有数据可以获得,但是雷达的电机没有转起来,这个时候计算的角度步长大小为一个异常值。

bug出现

代码在运行中,使用脚本进行改设备的有规律的上下电操作之后,出现了进程死掉的log展示839886cd3c004deb9abdba851aa48a4c.png

出现了此问题,第一时间是看log,但是log中没有什么有用的信息,所以我开始了gdb调试coredump文件

gdb分析

gdb exec coredump

展开之后使用bt命令就明显看到了内存溢出的问题image.png

看到第 16 帧可能为异常发生的地方

(gdb) f 16
#16 LiPkg::ToLaserscan (this=this@entry=0x55679e90b0, src=...) at /usr/src/debug/ld06-driver/git-r0/git/sdk/src/lipkg.cpp:239
239 in /usr/src/debug/ld06-driver/git-r0/git/sdk/src/lipkg.cpp
(gdb) info locals 
angle_increment = <optimized out>
beam_size = 4294967295

使用info locals之后看到此处函数里面beam_size为异常值839886cd3c004deb9abdba851aa48a4c.png

这里面我们看到beam_size算到了4294967295这样的一个值,这个值也是一个特殊值,42亿,是u32的最大值。

此外我们还在堆栈信息里面看到,改变量传入构造了一个vector,其中__n是很大的一个值

 0x00000055595e66e4 in std::vector<float, std::allocator<float> >::assign (__val=@0x7f8e189790: nan(0x400000), __n=4294967295, this=0x55679e9270) at /usr/include/c++/9.1.0/bits/stl_vector.h:746

所以我们打开相应的文件

vi usr/include/c++/9.1.0/bits/stl_vector.h +746839886cd3c004deb9abdba851aa48a4c.png

经过查看,我们发现__n 就是vector元素的计数,到这里,我们就明白了,是beam_size计算出错,导致的后面vector使用撑爆了。

打开执行的sdk源码,我们查看一下beam_size是怎么计算和使用的839886cd3c004deb9abdba851aa48a4c.png

我们看到 beam_size 为unsigned int,而计算它的数据都是float类型,而赋值的时候beam_size也没有用安全转换函数,那么我们基本可以肯定这应该是一次float类型转换的问题,那么看看数据到底是怎么算过来的呢。由于gdb调试的信息还是不够,所以我在下面又增加了log进行辅助分析。

增加log分析

在代码里面我增加了如下log打印

  unsigned int beam_size = ceil((angle_max - angle_min) / angle_increment);
  LOG_INFO("[lds driver] %s %d: beam_size:%d %f %f %f.", __FUNCTION__, __LINE__,beam_size,angle_max,angle_min,angle_increment);

839886cd3c004deb9abdba851aa48a4c.png

经过又一次执行崩溃之后,我们终于捕获到了它产生瞬间该函数里面的数据

[ WARN] [1501842255.254595539]: [lds driver] main 276: [lds driver] LD06 poll data timeout.
[ WARN] [1501842256.264604807]: [lds driver] main 276: [lds driver] LD06 poll data timeout.
[ INFO] [1501842257.042441093]: [lds driver] ToLaserscan 228: beam_size:-1 6.283180 0.000000 0.000000.
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

就是上面,我们看到这个时候 angle_increment 为0,但是实际上浮点不一定为0.000,而是后面可能有有一个小数没有表示出来,实际该浮点数可能为 0.000000000000001,而上面log可以看到,在打印beam_size之前,雷达处于无法读取数据的时候,为下电状态。下一瞬间可以读取数据,但是此时angle_increment计算为0.000000,计算angle_increment的电机实际速度应为为极小值,简单说应该是电机没有动作的起来,速度为0,导致计算beam_size转换之后变成一个极大值。

到这里我们就应该明白是如何造成的这个问题了。这个时候怎么修改呢?


bug修复

改bug的方法有很多种,哪一种好,能用就好。 这里我想到的就是把数据使用之前,进行安全检查,转化变量的时候进行static_cast修饰。

增加代码如下:

  /*Calculate the number of scanning points*/
  if(mSpeed > 0)
  {
    unsigned int beam_size = static_cast<unsigned int>(ceil((angle_max - angle_min) / angle_increment));
    ...
  }

显示效果如截图所示:839886cd3c004deb9abdba851aa48a4c.png

结语

这就是我使用乐动ld06型号雷达sdk的一些问题解决分享,这里面是一个完整工作解决bug的流程介绍,希望可以给大家一些知识补充。如果大家有更好的想法和需求,也欢迎大家加我好友交流分享哈。


作者:良知犹存,白天努力工作,晚上原创公号号主。公众号内容除了技术还有些人生感悟,一个认真输出内容的职场老司机,也是一个技术之外丰富生活的人,摄影、音乐 and 篮球。关注我,与我一起同行。


相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
6月前
|
分布式计算 DataWorks Java
DataWorks操作报错合集之在使用MaxCompute的Java SDK创建函数时,出现找不到文件资源的情况,是BUG吗
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
84 0
|
消息中间件 Arthas 监控
一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析
一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析
462 1
|
Java TensorFlow 算法框架/工具
Android TensorFlowLite sdk接入详细记录
前言 最近在研究ML的相关内容,开始在Android应用中接入TensorFlowLite。花了不少时间,添了不少坑,如果是裸的空项目接入还好,如果是现有的线上产品的接入,还是会有不少问题需要处理的,而且过程中,很多错误,网上的结论都是错误的,这个流程是我手把手一步步走的~亲测靠谱 先看效果 .
6082 0
|
开发工具 Android开发
从一个聚合SDK的Bug解决所展开的人生思考
最近,公司有个做聚合SDK的老铁要离职了,然后它的锅就甩给我了,话说,本来开会的时候说和另一个同事一人负责半个月 哎,我是一个落魄的小开发 那好吧,App这边目前也没有啥需求,然后就接手了这位老铁的聚合SDK的项目,本来是一个月的项目交接时间,非常奇葩的一个礼拜就走人了,一点都不夸张的,代码都还没有看完就已经要去和CP对接游戏了,直接上手开干,啰嗦了这么多,还没有扯到正题,好吧,我的锅,必须通过文字来小小的抱怨一下。
1652 0
|
开发工具
A bug in Flex SDK 3.4?? FocusManager.focusInHandler()
I have recently upgraded from Flex SDK 3.3 to SDK 3.4. Now I suddenly get this error message throughout the application: TypeError: Error #1009: Cann...
|
3月前
|
JavaScript 前端开发 Java
[Android][Framework]系统jar包,sdk的制作及引用
[Android][Framework]系统jar包,sdk的制作及引用
82 0
|
12天前
|
Java Linux API
Android SDK
【10月更文挑战第21天】
39 1