项目实训 - 智能车系统 - 第八周记录

项目实训 - 智能车系统 - 第八周记录

日期: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参数
    • 这个貌似是没用的,不需要tf的相关信息
  • 将ros的时间戳改成系统时间戳 input
    • 这里在ros的二次开发版本中,是使用ROS::time获取当前时间戳
    • 我的做法是获取了系统时间戳(system time),通过c++标准库实现
  • getPacket传入的参数是不是指针
  • 配置文件可能不全
    • 去网上搜到了一些配置文件,需要实际调试
时间戳处理问题

要注意的是,传出的数据包中,实际上包含了两个时间戳的信息:

  • 整个数据包的时间戳(获取系统时间戳)
  • 数据包中,点云中包含的timestamp信息

希望得到的时间戳

  • double类型,以sec为单位
  • 小数点后精确到us

分析雷达返回的时间格式

  • 后4byte数据可以直接拼出us部分
    • ms * 1e6 + us
  • 前6byte无法简单地得到sec部分,需要调用c标准库time.h

文档:https://en.cppreference.com/w/c/chrono/time_t

简单学习后,总结如下信息:

  • 头文件 <time.h>

  • 时间戳类:time_t,给类型返回一个整数,代表标准UTC时间戳,精确到sec

  • tm,一个结构体,成员如下:

    在这里插入图片描述

  • mktime:函数,将一个tm类型变量转换成time_t类型

demo实例:

#include <stdio.h>
#include <time.h>
#include <locale.h>
 
int main()
{
 
        // struct tm my_time = { .tm_year=112, // = year 2012
        //                   .tm_mon=9,    // = 10th month
        //                   .tm_mday=9,   // = 9th day
        //                   .tm_hour=8,   // = 8 hours
        //                   .tm_min=10,   // = 10 minutes
        //                   .tm_sec=20    // = 20 secs
        //                     };

    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");
    //my_time.tm_mon -= 100;  // tm_mon is now outside its normal range
    time_t timet = mktime(&my_time);       // tm_isdst is not set to -1; today's DST status is used
    // printf("100 months ago was %s", asctime(&my_time));
    // printf("(DST was %s)\n", my_time.tm_isdst ? "in effect" : "not in effect");
    printf("%ld\n", timet);


}

输出结果:

在这里插入图片描述

可以使用如上函数来处理得到需要的sec信息

定义了一个raw_time结构体,存储原始时间数据

/**
 * @brief 自定义用于解析数据包中的时间信息
 * raw data
 * 
 */
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;
}

接口

/**
 * @brief convert raw time info to timestamp(double, uint: s)
 * 
 * @param raw_time_data 
 * @return double 
 */
double RawData::get_timestamp(raw_time raw_time_data)
{
  //处理sec
  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);

  //处理nsec
  uint32_t nsec = raw_time_data.msecond * 1e6 + raw_time_data.usecond;

  //得到double类型时间戳
  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文件。这样一整个流程基本上就可以实现了。

安利一波新番 测不准的阿波连同学,萌翻了家人们。,。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值