·# 激光SLAM第三章作业去除运动畸变

一、原理

1、由于曲线可以通过分段来近似

二、题目介绍

1、题目描述

题目描述

1、本次的作业为实现一个里程计去除激光雷达运动畸变的模块
2、本次的作业里面有两个工程:champion_nav_msgs和LaserUndistortion;大家需要首先编译安装champion_nav_msgs,按照champion_nav_msgs的readme文件执行即可,注意根据自己ubuntu的不同版本做修改。

2、解题步骤

1.实现LidarMotionCalibration(插值并转化坐标系)函数,并进行编译
2.在LaserUndistortion下,进行source:source devel/setup.bash
3.运行launch文件,执行本条指令的时候,必须保证没有任何ros节点在运行,roscore也要关闭。
4.进入到 /bag目录下,运行指令:rosbag play –clock odom.bag。
5.如果一切正常,则会看到pcl的可视化界面,当可视化界面中存在数据的时候,按R键即可看到结果。红色为畸变矫正前,绿色为畸变矫正后。

三、代码框架

1、将原始激光数据转化到矫正需要的数据

2、进行矫正Lidar_Calibration函数

3、将矫正前后的数据转化到pcl中显示

四、函数解析

1、函数名

void Lidar_MotionCalibration(tf::Stamped<tf::Pose> frame_base_pose,tf::Stamped<tf::Pose> frame_start_pose,tf::Stamped<tf::Pose> frame_end_pose,std::vector<double>& ranges,std::vector<double>& angles,int startIndex,int& beam_number)

2、函数参数

 * @param frame_base_pose       标定完毕之后的基准坐标系* @param frame_start_pose      本分段第一个激光点对应的位姿* @param frame_end_pose        本分段最后一个激光点对应的位姿* @param ranges                激光数据--距离* @param angles                激光数据--角度* @param startIndex            本分段第一个激光点在激光帧中的下标* @param beam_number           本分段的激光点数量

3、函数代码

void Lidar_MotionCalibration(tf::Stamped<tf::Pose> frame_base_pose,tf::Stamped<tf::Pose> frame_start_pose,tf::Stamped<tf::Pose> frame_end_pose,std::vector<double>& ranges,std::vector<double>& angles,int startIndex,int& beam_number){//TODO//每个位姿进行线性插值时的步长double beam_step = 1.0 / (beam_number - 1);//机器人的起始角度和最终角度tf::Quaternion start_angle_q = frame_start_pose.getRotation();//getRotation()为获取四元数tf::Quaternion end_angle_q =  frame_end_pose.getRotation();//转换到弧度double start_angle_r = tf::getYaw(start_angle_q);double base_angle_r = tf::getYaw(end_angle_q);//机器人的起始位姿tf::Vector3 start_pos = frame_start_pose.getOrigin();//getOrigin()为获取平移向量start_pos.setZ(0);//最终位姿tf::Vector3 end_pos = frame_end_pose.getOrigin();end_pos.setZ(0);//基础坐标系tf::Vector3 base_pos = frame_end_pose.getOrigin();base_pos.setZ(0);double mid_angle;tf::Vector3 mid_pos;tf::Vector3 mid_point;double lidar_angle,lidar_dist;//插值计算每个点对应的位姿for (int i = 0; i < beam_number; ++i) {//角度插值mid_angle = tf::getYaw(start_angle_q.slerp(end_angle_q,beam_step * i));//slerp:球面线性插值方法//lerp:线性插值mid_pos = start_pos.lerp(end_pos,beam_step * i);//得到激光点在odom 坐标系中的坐标double tmp_angle;//如果range不等于无穷,则需要进行矫正//tfFuzzyZero()函数?if(tfFuzzyZero(ranges[startIndex + i]) == false){//计算对应的激光点在odom坐标系中的坐标//得到这帧激光束距离和夹角lidar_dist = ranges[startIndex+i];lidar_angle = angles[startIndex+i];//激光雷达坐标系下的坐标double laser_x,laser_y;laser_x = lidar_dist * cos(lidar_angle);laser_y = lidar_dist * sin(lidar_angle);//里程计坐标系下的坐标double odom_x,odom_y;odom_x = laser_x * cos(mid_angle) - laser_y * sin(mid_angle) + mid_pos.x();odom_y = laser_x * sin(mid_angle) + laser_y * cos(mid_angle) + mid_pos.y();//转换到类型中去mid_point.setValue(odom_x,odom_y,0);//把在odom坐标系中的激光数据点 转换到 基础坐标系double x0,y0,a0,s,c;x0 = base_pos.x();y0 = base_pos.y();a0 = base_angle_r;s = sin(a0);c = cos(a0);/** 把base转换到odom 为[c -s x0*                    s  c y0*                    0  0 1]* 把odom转换到base为 [c  s -x0*c-y0*s*                    -s c x0*s-y0*c*                    0  0 1]*/double tmp_x,tmp_y;tmp_x = mid_point.x()*c + mid_point.y() * s -x0*c -y0*s;tmp_y = mid_point.x()*s + mid_point.y() *c +x0*s - y0*c;mid_point.setValue(tmp_x,tmp_y,0);//然后计算以起始坐标为起点的 dist angledouble dx,dy;dx = (mid_point.x());dy = (mid_point.y());lidar_dist = sqrt(dx*dx + dy*dy);lidar_angle = atan2(dy,dx);//激光雷达被矫正ranges[startIndex+i] = lidar_dist;angles[startIndex+i] = lidar_angle;//基础坐标系下激光的距离和角度值}//如果等于无穷,则随便计算一下角度else{//激光角度lidar_angle = angles[startIndex+i];//里程计坐标系的角度tmp_angle = mid_angle + lidar_angle;tmp_angle = tfNormalizeAngle(tmp_angle);//如果数据非法 则只需要设置角度就可以了。把角度换算成start_pos坐标系内的角度lidar_angle = tfNormalizeAngle(tmp_angle - start_angle_r);angles[startIndex+i] = lidar_angle;}}//end of TODO}

主要思路:分段进行插值,得到每一束激光束对应的机器人位姿。并将该beam变成欧式坐标,再投影到世界坐标系下,再投影到base坐标系(整帧的第一个beam)下,再转换成极坐标,这样就将所有的beam修正到了base的极坐标系下

总结


参考了众多博客,学习了运动畸变去除的代码实现,但是代码中许多函数均未使用过,很不熟悉,自己实现起来还是很困难,需要在这方面继续努力。

激光SLAM第三章作业去除运动畸变相关推荐

  1. 《地球概论》(第3版)笔记 第三章 地球的运动

    目录 第三章 地球的运动 第六节 地球的自转 301 地球自转及其证明 302 地球自转的规律性 302-1 地轴和极移 302-2 地轴进动 302-3 地球自转的周期 302-4 真太阳日与平太阳 ...

  2. 《计算机网络》第三章作业

    <计算机网络>第三章作业 复习题 R3 考虑在主机A和主机B之间有一条TCP连接.假设从主机A传送到主机B的TCP报文段具有源端口号x和目的端口号y.对于从主机B传送到主机A的报文段,源端 ...

  3. 【编译原理】龙书第三章作业答案

    [编译原理]龙书第三章作业答案 练习3.1.1:根据3.1.2节中的讨论,将下面的C++程序划分成正确的词素序列.哪些词素应该有相关联的词法值?应该具有什么值? 答案: 左列为词素,右列为值,划分如下 ...

  4. 网络安全-技术与实践 | 第三章作业布置 by cdut 赵老师

    网络安全-技术与实践 | 第三章作业布置 by cdut 赵继老师 1:ARP的主要功能是将(IP)地址转换成为(物理)地址 注解:ARP:Address Resolution Protocol(地址 ...

  5. JAVA学习 第三章作业

    1.程序填空题: 定义一个抽象类Person,其中有一个公共的抽象方法showInfo().然后定义此抽象类的一个子类Student,包括的成员变量有姓名.学号.班级和年龄,且此类中包括两个构造方法. ...

  6. 从零开始手写VIO第三章作业(含关键点细节及思维过程)

    文章目录 前言·与同主题博文的不同 1.代码修改 1.1阻尼因子 µ 随着迭代变化的曲线图 1.2完成曲线y = ax^2^ + bx + c的参数估计 1.3实现其他更优秀的阻尼因子策略 2.公式推 ...

  7. 大学c语言第三章作业,华中科技大学光电子学院C语言第三章

    <华中科技大学光电子学院C语言第三章>由会员分享,可在线阅读,更多相关<华中科技大学光电子学院C语言第三章(20页珍藏版)>请在装配图网上搜索. 1.第三章 简单程序设计 1. ...

  8. 计算机组成原理 mov(r0),-(sp),第三章作业

    电子科技大学 廖建明 计算机组成原理第三章答案 2012060020029 王衡 1.某主存储器部分单元的地址码与存储器内容对应关系如下: 地址码存储内容 1000H A307H 1001H 0B3F ...

  9. 大学c语言第三章作业,c语言程序设计一章部分和第三章习题答案.doc

    c语言程序设计一章部分和第三章习题答案 实 验 报 告 课程名称 C语言程序设计A 实验项目 编程环境认知与顺序程序设计 实验仪器 PC机一台 学 院_____信息管理学院_______ 专 业 信息 ...

最新文章

  1. 2021年大数据Spark(五十二):Structured Streaming 事件时间窗口分析
  2. R 包 pathview 代谢通路可视化
  3. 肠里细菌“肚里蛔虫”:肠脑研究缘何越来越热
  4. maven 下载包冲突问题
  5. 微信小程序开发第二弹
  6. Qt QWidget实现消息提示控件TipsWidget
  7. leetcode - 101. 对称二叉树
  8. 知识资产投资——《程序员修炼之道》的建议
  9. 蓝桥杯 ADV-150算法提高 周期字串
  10. java iecapt.exe_java替换url的域名和端口方法
  11. clion环境搭建c++_mingw64_clion中使用python,ros-qt
  12. 洗衣机的维修和电动机
  13. 【JZOJ A组】时空幻境
  14. UWA学堂|开发流程模块
  15. Excel利用宏进行VBA编程
  16. Kali-WIFI攻防(一)----无线网络嗅探工具Kismet
  17. 电动自行车新国标正式发布,推动电池产业转型升级
  18. dbm与mysql_关于dBm与功率转换
  19. ⌈Linux_感受系统美学⌋ 一步一步迈向系统底层 - 寻觅Linux奥秘,探寻Linux下权限管理周边属性
  20. phpadmin的安装教程

热门文章

  1. 前端构建工具是什么?
  2. ubuntu18.0.4安装网卡驱动记录
  3. java并发编程实战wwj----------------------第二阶段-------Guarded Suspension-------24-25
  4. arduino 读取模拟电压_MQ2气体/烟雾传感器如何工作及其与Arduino接口
  5. C语言实现位图缩放bmp图片(使用命令行)
  6. 模板引擎FreeMarker的介绍和使用
  7. [渝粤教育] 西南科技大学 供应链管理 在线考试复习资料
  8. 数据质量管理_第四篇 对数变换
  9. C++ ifstream eof()的使用
  10. 铸铁的弹性模量和泊松比_常用材料的弹性模量及泊松比.pdf