?
后来,陆续做实验测试,终于发现问题所在。原来是前方DENSO雷达在往CAN卡上发送数据,而我程序当中并没有对此数据进行接收,导致内存泄露。即使是同一个CAN卡,
假如在程序当中不进行处理的话,也不行。之前一直认为,CAN API只会对一个CAN端口有效,现在看来不是,所以,对于同一个CAN设备,最好是在一个进程里面进行管理所有的端口,
有数据收发就接收和发送就行啦。不然会造成内存泄露。切记。切记。
参考资料:
http://bbs.csdn.net/topics/390292180 发送数据内存泄露,每次循环4k增加
http://bbs.csdn.net/topics/360163468 多线程运行时内存泄露
?
http://www.cnblogs.com/yixiaoyang/archive/2010/12/10/1902255.html
vs环境下的内存泄露检测工具
?
?
?
http://blog.csdn.net/wxqian25/article/details/17258407
BoundsChecker 使用
?
?
http://download.csdn.net/user/yth796/uploads/2
BoundsChecker 下载
?
官网:
http://supportline.microfocus.com/
?
可能原因:
同步那一块的问题, createThread的问题。试过,问题不在这。
用此函数试试,调用线程
?
2、关于CANET API的使用
为了使程序尽可能的稳定运行,使用的库最少化,改用周立功提供的CAN库进行编程。
在用下面的程序过程中,一开始死活配置不成功,总是在VCI_OpenDevice(); 后来,改配置通通都试了一遍还是不成功。
最后,自己写了一个测试程序,居然跑通了。最后的原因,应该还是项目的配置有问题。后来,该用新建的项目配置工程,完美解决。
也就是说,下次排查问题的时候,我们需要一项项进行测试,而不是整体测试。
- #ifndef WIN_CAN_H
- #define WIN_CAN_H
- ?
- #include <iostream>
- #include "ControlCAN.h"
- ?
- using
namespace std; - ?
- ?
- //CAN 相关
- ?
- const
static DWORD nDeviceType = VCI_CANETE; //设备类型 - const
static DWORD nDeviceInd = 0; //设备索引号 - const
static DWORD nCANInd = 0; //设备端口号 - ?
- class Win_Can
- {
- public:
- ???Win_Can(){}
- ???~Win_Can()
- ???{
- ??????VCI_CloseDevice(nDeviceType,nDeviceInd);
- ???}
- ?
- ????int write_to_can(VCI_CAN_OBJ frames[], int len) //支持发送多帧
- ???{
- ??????int ret = VCI_Transmit(nDeviceType,nDeviceInd,nCANInd,frames,len);
- ??????if (ret < 1)
- ??????{
- ?????????std::cout << "发送失败" << std::endl;
- ??????}
- ??????return ret;
- ???}
- ?
- ???int read_from_can(VCI_CAN_OBJ &frame) //一帧帧的读取
- ???{
- ??????int receiver = VCI_Receive(nDeviceType,nDeviceInd,nCANInd,&frame,1);//如果每次只接收一帧,是不是更好处理?
- ??????if (receiver <= 0)
- ??????{
- ?????????VCI_ReadErrInfo(nDeviceType,nDeviceInd,nCANInd,&errinfo);
- ??????}
- ??????return
true; - ???}
- ?
- ???bool init_can(string DesIP, int DesPort)
- ???{
- ??????/************************************************************************/
- ??????/* CAN卡初始化 */
- ??????/************************************************************************/
- ??????int nReserved = DesPort;
- ??????if (VCI_OpenDevice(nDeviceType,nDeviceInd,nReserved) != 1)
- ??????{
- ?????????std::cout << "打开设备失败,请检查设备类型和设备索引号是否正确" << std::endl;
- ?????????VCI_CloseDevice(nDeviceType,nDeviceInd);
- ?????????return
false; - ??????}
- ?
- ??????VCI_SetReference(nDeviceType,nDeviceInd,nCANInd,CMD_DESIP,(PVOID)DesIP.c_str());
- ??????VCI_SetReference(nDeviceType,nDeviceInd,nCANInd,CMD_DESPORT,(PVOID)&nReserved);
- ?
- ???VCI_ClearBuffer(nDeviceType,nDeviceInd,nCANInd);//清空缓冲区
- ????????return
true; - ???}
- ?
- public:
- ???VCI_ERR_INFO errinfo;
- ?
- };
- ?
- ?
- ?
- ?
- #endif
?
3、标定图像外参
图像外参主要有以下参数:
Wheel_Offset 85???? 相机到前轮中轴线的纵向距离
Head_Offset 168???? 相机到车前保险杠的纵向距离
Width_Offset_L 115???? 相机离左轮的横向距离
Width_Offset_R 63???? 相机离右轮的横向距离
Camera_tanr0 20.00 相机的pitch 角度
Camera_Height 138 相机离地面的高度
?
?
在调节pitch 角度的时候,我们有几种方式:
- 当两条直线的交点无法得到的时候,我们可以通过人为调节Camera_tanr0,然后查看逆透视的效果来标定,原则上,逆透视之后的车道线应该是平行的,当车道线不平行,说明标定有问题,我们需要调节角度。
- 还有一种方式,Camera_tanr0 不变,调节相机,我们可以看到识别到的车道线在变化。
下面是已经标定好的车道线示意图:
?
?
4、修改车道宽
之前图像程序中有一个bug,当没找到两条车道线的时候,人为的补上半个车道宽1.8m,当我们在检测到一条车道的时候,由于我们铺设的车道线不标准,导致卡丁车,路线来回抖动。
后来,加上一个获取前一次的车宽解决问题。
增加的代码如下:lane_width变成变量。
下图是检测到一条边和两条边的情况。图1是检测到一条边的情况,右侧车道线是虚拟中心线,自己补出来的。
图2 是检测到2条边的情况,中间的一条是虚拟中心线,通过左右车道线计算得到。