没有机器人,如何学习ROS编程

来源: 云巴巴 2020-05-08 14:16:01

ROS是目前最流行最全面的机器人操作系统,通过ROS上的编程学习,能够让我们切身体验各种机器人技术如何在现实中进行融合和使用。但是,一台支持ROS的机器人价格不菲,不像手机,说买就买。如果没有机器人,我们就没法学习ROS编程了吗?不可能!什么都不能阻挡我们拥抱ROS的热情和决心!这次就给同学们介绍一个开源的ROS机器人仿真项目,这个仿真项目集成了三维图形界面和物理惯性和碰撞引擎,脱离了物理世界的机器人实体,让我们坐着躺着就能把程序跑在一台ROS机器人上,看着它运动,看着它撞墙,看着它倒地……

一、开源项目网址

https://github.com/6-robot/wpr_simulation

注意:由于Indigo(Ubuntu 14.04)集成的Gazebo版本太过古老,已经失去维护无法使用。建议系统版本为Kinetic/Ubuntu 16.04以上版本。

二、开源项目的下载

在Ubuntu系统中,打开一个终端程序,输入如下指令下载项目源码:

cd catkin_ws/src

git clone https://github.com/6-robot/wpr_simulation.git

没有机器人,如何学习ROS编程

其中“catkin_ws”为ROS的工作空间,请根据电脑的环境设置进行修改。这个项目的源码是从Github网站下载的,所以下载过程需要连接互联网。

源码下载完成后,运行如下指令进行源码工程的编译:

cd ~/catkin_ws

catkin_make

 

没有机器人,如何学习ROS编程

这个开源工程,用到了Gazebo,如果之前安装的ROS是完整版本,则会很顺利的编译通过。如果编译过程中提示缺少某些依赖项,可以通过如下指令补充完整:

sudo apt-get install ros-kinetic-desktop-full

三、开源项目的使用

项目编译完成后,可以通过如下指令启动一个简单的仿真场景:

roslaunch wpr_simulation wpb_simple.launch

没有机器人,如何学习ROS编程

启动后,会弹出一个窗口,里面显示一台机器人,面对着一个柜子发呆:

没有机器人,如何学习ROS编程

这个就是仿真环境的主界面,可以看到界面的周围有很多的工具按钮和菜单列表,这些我们会在后续的教程中进行介绍,这次先跳过,直接进入ROS编程的正题。

四、和ROS程序的连接

仿真环境运行起来了,下面看看如何与ROS程序进行连接。这里准备了一个简单的速度控制程序作为例子,可以运行起来体验一下。保持刚才启动的仿真环境别关闭,在Ubuntu系统中再新打开一个终端,输入如下指令:

rosrun wpr_simulation demo_vel_ctrl

没有机器人,如何学习ROS编程

 

运行之后,可以看到机器人开始向前缓慢移动,直到撞上柜子……

 

没有机器人,如何学习ROS编程

五、示例程序源码解析

这个demo_vel_ctrl就是一个简单的ROS机器人速度控制程序,它的源代码位置:

~/catkin_ws/src/wpr_simulation/src/ demo_vel_ctrl.cpp

我们可以用Visual Studio Code之类的IDE打开这个源码文件:

#include <ros/ros.h>

#include <geometry_msgs/Twist.h>

 

int main(int argc, char** argv)

{

ros::init(argc, argv, "demo_vel_ctrl");

 

ros::NodeHandle n;

ros::Publisher vel_pub = 

n.advertise<geometry_msgs::Twist>("/cmd_vel", 10);

 

while (ros::ok())

{

geometry_msgs::Twist vel_cmd;

vel_cmd.linear.x = 0.1;

vel_cmd.linear.y = 0.0;

vel_cmd.linear.z = 0.0;

vel_cmd.angular.x = 0;

vel_cmd.angular.y = 0;

vel_cmd.angular.z = 0;

vel_pub.publish(vel_cmd);

ros::spinOnce();

}

 

return 0;

}

(1) 代码的开始部分,先include了两个头文件,一个是ros的系统头文件,另一个是运动速度结构体类型geometry_msgs::Twist的定义文件;

(2) ROS节点的主体函数是int main(int argc, char** argv),其参数定义和其他C++程序一样;

(3) main函数里,首先调用ros::init(argc, argv, "demo_vel_ctrl");进行该节点的初始化操作,函数的第三个参数是节点名称;

(4) 接下来声明一个ros::NodeHandle对象n,并用n生成一个广播对象vel_pub,调用的参数里指明了vel_pub将会在主题“/cmd_vel”里广播geometry_msgs::Twist类型的数据。我们对机器人的控制,就是通过这个广播形式实现的。这里就有一个疑问:为什么是往主题“/cmd_vel”里广播数据而不是其他的主题?机器人怎么知道哪个主题里是要执行的速度?
答案是:在ROS里有很多约定俗成的习惯,比如激光雷达数据发布主题通常是“/scan”,坐标系变换关系的发布主题通常是“/tf”,所以这里的机器人速度控制主题“/cmd_vel”也是这样一个约定俗成的情况。

(5) 为了连续不断的发送速度,使用一个while(ros::ok())循环,以ros::ok()返回值作为循环结束条件可以让循环在程序关闭时正常退出。

(6) 为了发送速度值,声明一个geometry_msgs::Twist类型的对象vel_cmd,并将速度值赋值到这个对象里。其中:

(7) vel_cmd.linear.x是机器人前后平移运动速度,正值往前,负值往后,单位是“米/秒”;

(8) vel_cmd.linear.y是机器人左右平移运动速度,正值往左,负值往右,单位是“米/秒”;

(9) vel_cmd.angular.z(注意angular)是机器人自转速度,正值左转,负值右转,单位是“弧度/秒”;

(10) 其他值对启智机器人来说没有意义,所以都赋值为零。

(11) vel_cmd赋值完毕后,使用广播对象vel_pub将其发布到主题“/cmd_vel”上去。机器人的核心节点会从这个主题接收我们发过去的速度值,并转发到硬件底盘去执行。

调用ros::spinOnce()函数给其他回调函数得以执行。

可以看到这是一个标准的ROS程序,在实体机器人上,它实现的是让机器人以0.1米/秒的速度往前推进,在这个仿真环境里,机器人也是执行了相同的行为。

六、和ROS系统工具的连接

在这个仿真环境里,是否可以正常的使用ROS的系统工具?我们来实践一下,启动一个Rviz工具,显示机器人采集到的传感器数据。为了省去繁琐的配置工作,这里我们直接下载一个现成的ROS机器人开源代码。打开一个新的终端程序,输入如下指令:

cd ~/catkin_ws

git clone https://github.com/6-robot/wpb_home.git

 

没有机器人,如何学习ROS编程

下载完成后,再次进行编译:

cd ~/catkin_ws

catkin_make

没有机器人,如何学习ROS编程

保持刚才启动的仿真环境别关闭,在Ubuntu系统新打开一个终端,输入如下指令:

roslaunch wpr_simulation wpb_rviz.launch

没有机器人,如何学习ROS编程

 

运行指令后,就会弹出ROS标配的图形显示界面Rviz,里面显示的就是仿真环境中的虚拟机器人所感知到的各种数据:

 

没有机器人,如何学习ROS编程

 

  • 右侧主界面里显示的是机器人头部的立体相机采集到的三维点云。

  • 柜子底部的红色点阵是机器人底盘激光雷达扫描到的障碍物边缘。

  • 左下角的视频图像是机器人头部彩色相机采集到的数据。

在机器人运动的过程中,上述数据都会实时的变化,可以很直观的测试我们编写的机器人控制程序。

七、基于传感器数据的闭环控制

下面我们再看看一个复杂一点的例子,在一个标准的ROS程序里,获取机器人从仿真环境里采集到的数据,再反馈回去控制仿真环境里的虚拟机器人。整个程序的实现思路:

没有机器人,如何学习ROS编程

从如下地址可以找到这个程序的源代码文件:

~/catkin_ws/src/wpb_home/wpb_home_tutorials/

src/wpb_home_lidar_behavior.cpp

我们可以用Visual Studio Code之类的IDE打开这个源码文件:

#include <ros/ros.h>

#include <std_msgs/String.h>

#include <sensor_msgs/LaserScan.h>

#include <geometry_msgs/Twist.h>

 

ros::Publisher vel_pub;

static int nCount = 0;

 

void lidarCallback(const sensor_msgs::LaserScan::ConstPtr& scan)

{

int nNum = scan->ranges.size();

 

int nMid = nNum / 2;

float fMidDist = scan->ranges[nMid];

ROS_INFO("Point[%d] = %f", nMid, fMidDist);

 

if (nCount > 0)

{

nCount--;

return;

}

 

geometry_msgs::Twist vel_cmd;

if (fMidDist > 1.5f)

{

vel_cmd.linear.x = 0.05;

}

else

{

vel_cmd.angular.z = 0.3;

nCount = 50;

}

vel_pub.publish(vel_cmd);

}

 

int main(int argc, char** argv)

{

ros::init(argc, argv, "wpb_home_lidar_behavior");

 

ROS_INFO("wpb_home_lidar_behavior start!");

 

ros::NodeHandle nh;

ros::Subscriber lidar_sub = nh.subscribe("/scan", 10, &lidarCallback);

vel_pub = nh.advertise<geometry_msgs::Twist>("/cmd_vel", 10);

 

ros::spin();

}

源码解析:

(1) 代码的开头include了四个头文件:ros.h是ros的系统头文件;String.h是字符格式的定义文件,用来做文字输出;LaserScan.h是激光雷达的数据格式定义文件,用来装载雷达数据;Twist.h是机器运动速度消息包的格式定义文件,对应的Twist消息包格式如下:

没有机器人,如何学习ROS编程

其中linear是运动控制的线性分量,也就是机器人直线移动的分量,angular是机器人旋转运动的分量。这两个分量都是Vector3类型,其结构定义如下:

没有机器人,如何学习ROS编程

可见Vector3类型包含三个浮点数:x、y和z。对于linear来说,x、y和z对应的是沿X轴、Y轴和Z轴方向上的速度分量,分量数值单位为“米/秒”。对于angular来说,x、y和z对应的是以X轴、Y轴和Z轴为旋转轴的旋转速度分量,分量数值单位为“弧度/秒”。

(2) 程序接下来定义一个消息发布对象vel_pub,后面会用这个发布对象向机器人核心节点发送速度控制消息包。因为机器人转向行为需要维持一段时间,才能转到完全避开障碍物的方向,所以这里定义了一个int型变量nCount,用来调整机器人转向动作的时长。

(3) 定义一个回调函数void lidarCallback(),用来处理激光雷达数据。ROS每接收到一帧激光雷达数据,就会自动调用一次回调函数。雷达的测距数值会以参数的形式传递到这个回调函数里。

(4) 在回调函数void lidarCallback()中,参数scan是一个sensor_msgs::LaserScan格式的数据包,其数据格式定义如下:

没有机器人,如何学习ROS编程

其中float32[] ranges数组存放的就是激光雷达的测距数值。启智ROS机器人使用的是RPLidar A2型号激光雷达,其旋转一周测量360个距离值,所以在我们的代码里,ranges是一个360个成员的距离数组。

按照程序逻辑,我们需要的是机器人正前方的测距数值,根据激光雷达在机器人上的安装位置,激光雷达的扫描角度如下图所示:

没有机器人,如何学习ROS编程

从图中可知机器人正前方的激光射线角度为扫描角度范围的中间值,我们定义一个变量nNum,用来获取ranges数组的成员个数。再定义一个变量nMid,值为nNum的一半,由上图可知,nMid对应的激光雷达扫描线序即为机器人正前方的扫描线,以nMid作为下标从ranges数组里取到的值即为机器人正前方的雷达测距数值,我们将这个测距值保存到变量fMidDist中。fMidDist中的数值为一个小数,数值单位为“米”。我们使用ROS_INFO()将机器人正前方的雷达测距数值fMidDist显示到终端程序里,方便我们观察和调试。

接下来是对nCount的一个数值判断:如果nCount大于0,则将nCount减一,并直接return中断这个回调函数,让机器人维持之前的运动状态直到nCount递减到0。这就实现了通过给nCount赋值来控制机器人转向动作时长的功能。

程序里定义了一个geometry_msgs::Twist消息包vel_cmd,用来装载我们要发送的机器人运动控制量,然后根据fMidDist的数值大小来对vel_cmd进行不同的赋值。当fMidDist大于1.5时,也就是机器人正前方的障碍物距离大于1.5米的时候,我们给vel_cmd的x赋值0.05,控制机器人以0.05米/秒的速度缓慢向前移动;当fMidDist不大于1.5时,也就是机器人正前方的障碍物距离小于或等于1.5米的时候,我们给vel_cmd的z赋值0.3,控制机器人以0.3弧度/秒的速度原地向左旋转,同时对nCount赋值50,让机器人在后面的50次回调函数执行过程中都维持这个旋转动作。对vel_cmd赋值完毕后,通过vel_pub将其publish发布到相关主题上,启智ROS的核心节点会从主题中获得这个数据包,并按照我们赋值的速度对机器人底盘进行运动控制。

(5) 在主函数main()中,调用ros::init(),对这个节点进行初始化。

(6) 调用ROS_INFO()向终端程序输出字符串信息,以表明节点正常启动了。

(7) 定义一个ros::NodeHandle节点句柄nh,并使用这个句柄向ROS核心节点订阅“/scan”主题的数据,回调函数设置为之前定义的lidarCallback()。

(8) 使用节点句柄nh对vel_pub进行初始化,让其在主题“/cmd_vel”发布速度控制消息,启智ROS的核心节点会从这个主题获取vel_pub发布的消息,并控制机器人底盘执行消息包里的速度值。

(9) 调用ros::spin()对main()函数进行阻塞,保持这个节点程序不会结束退出。

这个程序在前面我们已经编译过了,这里直接执行即可。保持刚才启动的仿真环境别关闭,在Ubuntu系统新打开一个终端,输入如下指令:

rosrun wpb_home_tutorials wpb_home_lidar_behavior

没有机器人,如何学习ROS编程

这条指令会启动刚才的wpb_home_lidar_behavior程序。按照程序逻辑,会从激光雷达的“/scan”主题里不断获取激光雷达数据包,并把机器人正前方的激光雷达测距数值显示在终端程序里。终端里显示“Point[180] = xxxx”其中xxxx为一个浮点数,单位是“米”。比如“Point[180] = 2.626860”表示机器人正前方的激光雷达测距值为2.626860米。

 

没有机器人,如何学习ROS编程

这时切换到仿真环境界面,可以观察机器人的运行效果:

(1) 程序启动后,机器人开始以0.05米/秒的速度向前移动。

(2) 当机器人前方1.5米处出现障碍物时,机器人停止移动,以0.3弧度/秒的速度原地转动。

(3) 当机器人转到前方1.5米范围内没有障碍物时,停止转动,继续以0.05米/秒的速度向前移动。

没有机器人,如何学习ROS编程

八、问题反馈

至此,关于这个仿真项目的简单体验就介绍完了,如果同学们在安装和使用过程中遇到问题,可以在这个项目的Github主页上提交issuse,我们会及时回复,让其他遇到类似问题的小伙伴也能看到。提交issuse的方法:

(1) 在浏览器中打开项目的Github主页:

https://github.com/6-robot/wpr_simulation

(2) 点击分页栏的第二项“Issues”切换页面:

没有机器人,如何学习ROS编程

(3) 在“Issues”页面中点击“New issue”即可提交新的issuse:

没有机器人,如何学习ROS编程

九、后续更新

在这个系列后续的文章里,我们还会详细介绍Gazebo这个仿真环境的使用。同时这个开源项目也会继续持续更新,添加越来越多的新功能,比如SLAM环境建图、路径规划与导航、语音识别、人脸识别、物品识别、物品抓取……等等等等,也欢迎各位同学在“Issues”中给我们新的想法和反馈。

如果你喜欢这个项目,麻烦不要吝啬手中的鼠标,素质三连!赏给我们一颗小星星!您的满意是我们持续更新的最大动力!谢谢~~我们下次再见!(比心❤)

没有机器人,如何学习ROS编程

没有机器人,如何学习ROS编程

更多产品了解

欢迎扫码加入云巴巴企业数字化交流服务群

产品交流、问题咨询、专业测评

都在这里!

 

评论列表

为你推荐

生物识别的多模态识别趋势发展

生物识别的多模态识别趋势发展

现今,随着物联网、大数据、云计算、人工智能等技术的进展迅速,生物识别技术也得到了很大的发展,根据前瞻性行业研究,预计今年全球生物识别总市场将达到250亿$。 在国内市场方面,2010至2014年,国内生物特征识别市场的平均增速保持在60%以上。

2020-04-14 17:43:44

科技,数据管理与人工智能的桥梁

科技,数据管理与人工智能的桥梁

都说科技改变生活,但这句话又相对抽象,就今天的主题来说,科技起到的作用,就是充当数据管理与人工智能的桥梁。 人工智能的商业行为与传统软件的一个非常重要的方面:它必须是如何通过完成其工作。这为产品进行生命周期提供了一个重要关键好处,

2020-04-29 17:12:20

放眼身边,我们身边的人工智能你知道哪些?(上)

放眼身边,我们身边的人工智能你知道哪些?(上)

提起人工智能,相信大家脑海里会出现“机器人”、“智能家居”等一些词语,而在我们日常使用的人脸识别中也有人工智能的应用。不仅仅是我们对着手机通过自己的声音完成认证之后打开手机助手,我们身边越来越多的领域内其实都有人工智能的身影。而人工智能又分为强人工智能和弱

2022-11-23 16:58:11

虹膜识别一般指虹膜识别技术的优缺点

虹膜识别一般指虹膜识别技术的优缺点

在小编的前几篇文章中,已经介绍了有关于虹膜识别技术的识别过程是怎样的,本篇文章,小编就简单介绍一下,虹膜识别一般指虹膜识别技术的优缺点都有哪些。 虹膜识别技术的优点,便于用户使用,可能会是最可靠的生物识别技术,不需物理的接触,可靠性高。虹膜识别技术的配置

2022-11-21 13:49:04

云巴巴案例秀 ‖ 汽配行业高效数字化工厂,快速解决报工难题

云巴巴案例秀 ‖ 汽配行业高效数字化工厂,快速解决报工难题

打造数字化透明工厂就是这么简单,黑湖小工单就是一款超轻量的生产管理小程序,能够敏捷管理生产、库存、设备等核心制造流程,灵活适应工厂的个性化管理模式。

2024-03-27 14:25:40

腾讯云ocr识别的产品特点都有哪些

腾讯云ocr识别的产品特点都有哪些

OCR识别技术极大程度的提高了我们生活、通行、和工作的效率,随着现在 OCR技术的普及,越来越多的厂家开始研发并发售 OCR识别产品。国内一流大厂腾讯云、阿里云、百度云都有对应的 OCR识别产品,本文,就和朋友们一起来看一下腾讯云的 OCR识别的产品特点吧

2022-11-24 10:01:04

严选云产品

腾讯服务器资源优化方案 腾讯服务器资源优化方案是腾讯在控本提效的三个方案研究,主要包括腾讯能耗节省-悟能方案、腾讯混部解决方案-如意、内存节省方案-悟净三个方面。极致性能优化,降低生成过程延时,提高吞吐量。 面向生产落地,根据实际需求来调整推理策略。
网易易盾智能风控 易盾智能风控系统具备强大的客户端识别能力 - 风控SDK,实现客户端作弊工具、异常设备环境、异常内存行为等检测,可识别结果更加丰富,且可识别输出内容下探更细节的环节,比如模拟器品牌、作弊工具类型等。
环信客服系统游戏行业解决方案 客服是游戏发行方、研发方直面玩家的第一途径,直接代表了产品和公司整体形象。除去游戏本身的内容外,客服即是玩家对于游戏的最主要印象,良好的客服人员可以在解决玩家问题的同时为玩家营造轻松愉悦的反馈体验,从而赢得玩家信任。
数字档案平台 数字档案平台就是将所有档案实行统一管理,实现资源共享,是通过计算机和网络技术手段整合信息资源,打破信息割据,最大化地进行开发利用,避免造成信息资源的浪费。
商汤睿目通行一体机SensePass S7 SensePass S7 睿目通行一体机,集成了商汤科技最新AI识别算法,采用7寸高清触控显示屏、200万像素双目高动态摄像头,具备IP66防水防尘等级,支持多种标准接口拓展,适用于各种复杂环境。可结合管理平台提供身份核验、门禁通行、考勤签到、访客迎宾等多场景一站式服务。
同创永益IStorM BCMS业务连续性管理平台 IStorM BCMS业务连续性管理系统遵循国内外业务连续性管理标准、规范和最佳实践,通过线上动态业务影响分析、风险分析实现业务连续性策略、计划及预案的体系化管理,敏捷构建应急响应机制,自动化实现事件应急处置,简化演练的发起、组织全过程,通过实时管控和标准化监管报送帮助用户构建全面合规的业务连续性管理体系。

甄选10000+数字化产品 为您免费使用

申请试用