使用ROS开源代码和激光雷达进行小车的定位导航

4 篇文章 1 订阅
2 篇文章 0 订阅

前面的话

             之前我做了一个使用激光雷达进行定位的项目,开始了一段时间对ROS、激光雷达的slam等应用的研究。以下我只是记录下我学习的历程以及一些结论,供大家参考。下面主要分为以下四个部分分别进行介绍。

一、前期准备

 

        在前期准备阶段我们需要掌握一定的其他方面的知识

        1.linux令的使用:要求能记住一些基本命令其他的多用多查不要依赖鼠标就好。

            下面是一个比较好的网址     http://www.runoob.com/linux/linux-command-manual.html

        2.vim的使用。我们编写ROS的程序时一般是采用vim来编写的,所以基本的vim还是需要了解的。

            可以参考我学习时看的vim的博客  vim—从零开始      

       3.对ROS框架了解,维基百科上的教程已经给的很详细了。

二、熟悉框架

 

下面我假设大家都完成了上面的准备工作。

那么我开始介绍一个定位与导航框架的搭建的大致思路

1.获得运动模型,tf树,激光雷达的数据。

2.调用ros进行建图,比如我目前采用的gmapping算法

3.定位

4.进行全局路径规划

5.局部路径规划

如果是第一次接触这些东西的话难免会有一些陌生感,下面我也不做过多的介绍(我介绍的没有其他大神介绍的好)

所以我给出下面一些网址,希望新手阅读一遍先,当然很熟悉的话也可以直接跳过。

1.运动学模型   在这里我们采用的四个全向轮的底盘如图所示

https://blog.csdn.net/banzhuan133/article/details/69229922

当然这种底盘的运动学方程别人已经求解过了,我们只需要使用结果就好,具体的过程参照上面的博客

我们只需要用到

其他的如tf树等在后面会具体介绍。

2.使用激光雷达数据进行建图

目前激光雷达建图有很多的开源算法,我采用的是目前应用的比较广泛的gmapping算法。

当然有大神做过几种slam算法的比较

https://blog.csdn.net/u012700322/article/details/52953768

当然这些博客中很少提及算法的实现原理,希望了解建图的具体实现原理的同学可以参考coursera里面的robotics的课程,课程大致介绍了通用的原理,如果还想更具体的了解推荐《概率机器人》这本书,但是友情提醒这本书很贵而且包含大量数学知识很难看懂。

3.定位

定位就是在已知地图中利用激光雷达的信息确定机器人目前的姿态和位置。我们采用的是ros中自带的自适应蒙特卡洛定位算法,目前来说这种算法还是比较流行而且效果较好。

什么是蒙特卡洛呢?参考下面的博客蒙特卡洛算法的简单理解

下面这篇知乎大致说了蒙特卡罗定位的基本思路

当然我们用的自适应蒙特卡罗定位还是不止这么简单,具体的可以阅读一些源码。

4.全局路径规划

全局路径规划有两种算法,我们采用A*算法

当然网上a*算法介绍的很多我就不再重复

5.局部路径规划

局部的网上没有太多的介绍,我还是推荐维基百科的介绍

三、搭建框架

下面让我们兴奋的拿起电脑,因为终于要实战。

首先我讲一下我电脑的配置

Ubuntu16.06+ROS(kinetic)

emmm。。。有点累了下次再说吧。拜拜~~~~

代码链接附上,17年做的了,可能有bug,勿喷。

https://github.com/linyicheng1/ICRA-electronics-design-competition 

以下是一个简单的ROS小车的司岚A1激光雷达跟随功能C++代码: ```cpp #include <ros/ros.h> #include <sensor_msgs/LaserScan.h> #include <geometry_msgs/Twist.h> class LaserFollower { public: LaserFollower() { scan_sub_ = nh_.subscribe<sensor_msgs::LaserScan>("scan", 10, &LaserFollower::scanCallback, this); cmd_pub_ = nh_.advertise<geometry_msgs::Twist>("cmd_vel", 10); } void scanCallback(const sensor_msgs::LaserScan::ConstPtr& scan) { const float min_follow_distance = 0.5; // 最小跟随距离 const float max_follow_distance = 1.0; // 最大跟随距离 const float follow_angle = 0.0; // 跟随角度 const float follow_speed = 0.2; // 跟随速度 int num_ranges = scan->ranges.size(); if (num_ranges == 0) { return; } float angle_min = scan->angle_min; float angle_increment = scan->angle_increment; float angle_max = angle_min + (num_ranges - 1) * angle_increment; float follow_angle_min = follow_angle - angle_increment; float follow_angle_max = follow_angle + angle_increment; int follow_index = -1; float follow_range = max_follow_distance; for (int i = 0; i < num_ranges; i++) { float angle = angle_min + i * angle_increment; float range = scan->ranges[i]; if (angle < follow_angle_min || angle > follow_angle_max) { continue; } if (range < min_follow_distance || range > max_follow_distance) { continue; } if (range < follow_range) { follow_index = i; follow_range = range; } } if (follow_index != -1) { float follow_error = follow_range - min_follow_distance; float follow_speed_cmd = follow_speed * follow_error / (max_follow_distance - min_follow_distance); geometry_msgs::Twist cmd_vel; cmd_vel.linear.x = follow_speed_cmd; cmd_vel.angular.z = (follow_index - num_ranges / 2) * angle_increment * 2; cmd_pub_.publish(cmd_vel); } } private: ros::NodeHandle nh_; ros::Subscriber scan_sub_; ros::Publisher cmd_pub_; }; int main(int argc, char** argv) { ros::init(argc, argv, "laser_follower"); LaserFollower laser_follower; ros::spin(); return 0; } ``` 这段代码使用ROS的LaserScan消息订阅激光雷达数据,并根据指定的跟随距离和角度,计算出跟随的目标点,并根据目标点和车辆当前位置的差距,输出相应的速度指令,以实现跟随功能。其中,linear.x和angular.z分别表示小车的线速度和角速度,可以根据实际情况进行调整。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值