项目实训 - 智能车系统 - 第八周记录
日期:4.11 – 4.17
项目进度
本周工作进展:
- 完成了雷达驱动的编写(未测试)
- 完成imu驱动的编写(未测试)
- 与可视化部分进行对接
1、速腾rslidar驱动编写(二次开发)
通过阅读ROS二次开发的rslidar驱动后,决定延用之前移植项目的做法,在ros二次开发的版本的基础上进行修改,将发布的数据修改我们自定义的类型,并且发布数据。
另一个节点rs_to_velodyne订阅上面发布的消息,将数据转换成velodyne的点云格式,然后进行发布,被项目订阅。
具体移植过程不做记录,这里记录一下开发过程中的一些问题。
可能产生的问题记录
由于封校原因,暂时无法拿到雷达,所以无法直接对编写好的驱动进行测试,所以记录了一下移植后可能产生的问题:
- height和width的问题
- rslidar发布的点云数据是有序的(height!=1 ),但是阅读lio-sam后,发现lio-sam获取的数据是无序的(height == 1 ),二者出现了差异
- 我的做法是在驱动中直接将点云数据按照heght=1的情况进行存储,然后发布
- point.at的问题
- 也是上面的问题,由于点云存储方式的不同,定位到每个点的时候,也可能出现乱序的情况
- 时间戳的起始问题
- 时间数据流的大端法和小端法
- 这个是传入的数据流的存储方式问题,根据雷达手册暂时无法区分
- 需要具体测试
- 从参数服务器中获取tf参数
- 将ros的时间戳改成系统时间戳 input
- 这里在ros的二次开发版本中,是使用ROS::time获取当前时间戳
- 我的做法是获取了系统时间戳(system time),通过c++标准库实现
- getPacket传入的参数是不是指针
- 配置文件可能不全
时间戳处理问题
要注意的是,传出的数据包中,实际上包含了两个时间戳的信息:
- 整个数据包的时间戳(获取系统时间戳)
- 数据包中,点云中包含的timestamp信息
希望得到的时间戳
- double类型,以sec为单位
- 小数点后精确到us
分析雷达返回的时间格式
- 后4byte数据可以直接拼出us部分
- 前6byte无法简单地得到sec部分,需要调用c标准库time.h
文档:https://en.cppreference.com/w/c/chrono/time_t
简单学习后,总结如下信息:
demo实例:
#include <stdio.h>
#include <time.h>
#include <locale.h>
int main()
{
struct tm my_time;
my_time.tm_year = 112;
my_time.tm_mon = 9;
my_time.tm_mday = 9;
my_time.tm_hour = 8;
my_time.tm_min = 10;
my_time.tm_sec = 21;
printf("Today is %s", asctime(&my_time));
printf("(DST is %s)\n", my_time.tm_isdst ? "in effect" : "not in effect");
time_t timet = mktime(&my_time);
printf("%ld\n", timet);
}
输出结果:
可以使用如上函数来处理得到需要的sec信息
定义了一个raw_time结构体,存储原始时间数据
struct raw_time
{
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint16_t msecond;
uint16_t usecond;
}
接口
double RawData::get_timestamp(raw_time raw_time_data)
{
struct tm cur_time;
cur_time.tm_year = raw_time_data.year + 100;
cur_time.tm_mon = raw_time_data.month - 1;
cur_time.tm_mday = raw_time_data.day;
cur_time.tm_hour = raw_time_data.hour;
cur_time.tm_min = raw_time_data.minute;
cur_time.tm_sec = raw_time_data.second;
uint32_t sec = mktime(&tm);
uint32_t nsec = raw_time_data.msecond * 1e6 + raw_time_data.usecond;
return (static_cast<double>(sec) + 1e-9*static_cast<double>(nsec));
}
测试基本没啥问题
- 问题:需要判断雷达得到的数据流是大端法还是小端法
- 会丢失一点us的精度
2、imu驱动编写
这个部分有学长提供的imu手册,对照着直接编写即可,不做具体记录
3、与可视化的对接
这个部分比较顺利,因为之前的接口已经定义好的,所以运行项目和可视化之后,直接就可以正常运行了,效果图如下(因为之前订阅的是registered_raw点云数据,没有经过降采样,所以看起来有点糊)
右边是rivz的运行效果,左侧是自定义效果
流程(接收端暂时还是使用ros的机制):
- rosbag启动数据包
- lio-sam项目启动,接收数据,处理后发布数据
- 可视化接收lio-sam发布的数据,继续渲染
技术难点
socket通信
bug记录
没啥大bug
其他
下周预计完全去除项目中的ros相关的东西(之前方便调试,有些变量函数都没有删除),重写一个cmake文件。这样一整个流程基本上就可以实现了。
安利一波新番 测不准的阿波连同学,萌翻了家人们。,。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)