立即咨询

电话咨询

微信咨询

立即试用
商务合作

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

2020-05-08

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编程

更多产品了解

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

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

都在这里!

 

热门数字化产品

纷呈科技电商开票软件纷呈科技电商开票软件实现多平台店铺订单一站式自动开票,无需托管税盘,企业自行管理,自动同步店铺订单及订单开票信息,在线批量、自动完成订单开票,自动回传发票至各电商平台,买家实时下载,覆盖所以税盘类型,多种模式操作,可自动、批量、单个实现订单开票。
Oracle NetSuite云ERP系统Oracle NetSuite云ERP系统是一个集成的云端企业资源规划平台,提供财务管理、供应链、CRM和电子商务管理等功能,支持全球业务扩展,加速企业创新和增长。
句子互动SCRM系统句子互动SCRM系统,把企业微信账号变成机器人,实现更效率和高频次的触达。基于预设规则和对象特征,让消息推送更智能更精准。 帮助企业打通内外部系统的数据系统,实现更多灵活、更个性化的营销和服务能力开发。同时支持私有部署、iframe嵌入等多种系统接入方式。
腾讯乐享企业培训管理系统腾讯乐享连接知识、沉淀经验,整合学习地图、课堂、考试、直播、文档、社群、问卷、员工关怀、项目管理、讲师管理等多应用于一体,帮助团队建立学习型组织、降低沟通成本,提升员工自发性和组织内协同性,助力企业数字化管理升级。
SaleSmartly智能客服工具SaleSmartly智能客服工具中一个面板回复所有渠道咨询,随时随地,一键快速回复大量咨询,SaleSmartly解决都是外国客人咨询,需配备懂外语的客服而导致 成本高的问题。通过客户的提问或行为,自动回复和解决其常见问题。可通过个性化的设置,对用户不同关键词或行为, 触发不同的自动回复及自动化流程。
为你推荐
2025腾讯产业合作伙伴大会|云巴巴荣获双项大奖,载誉而归

1月16日,2025腾讯产业合作伙伴大会在三亚召开。云巴巴,荣膺“2024腾讯云卓越合作伙伴奖—星云奖”和“2024腾讯云AI产品突出贡献奖”双项大奖

2025-01-17
跨境企业突围战!优刻得云主机破解合规、延迟、成本三大难题

面对跨境行业的出海需求呈现爆发式增长问题,如何构建一张高效、安全、智能的全球网络,成为企业出海成功的关键。

2025-04-29
出行服务平台如何利用私域做好运营?四大步骤助公私域流量衔接与转化

优秀的私域营销平台句子以“下一代营销云”为核心,为出行服务平台构建了从引流、沉淀到持续激活的闭环运营体系,直击行业痛点。

2025-04-29
电商大促如何破局?深度分析TAPD如何成为GMV增长的核心引擎?

如何选型一款工具,既能在流量洪流中稳抓机遇,同时避免资源内耗与系统崩溃?

2025-04-28
几十家店铺开票如打仗?小望电商通让财务告别手忙脚乱

在电商行业高速发展的今天,多平台、多店铺运营已成为企业常态,如何选择一款既能提升效率又能保障合规的智能开票工具是企业当前最为头疼的难题。

2025-04-28
查看更多