标签:
最近学习了ROS机器人系统,大家都知道ROS是基于Linux平台,当然如果把ROS应用到Windows、Android、IOS、WP系统也可以,只要下载对应的ROS开发包就行了,但是配置这些环境是一件很蛋疼的事情,因为ROS有很多版本,不是每一个版本都有对应平台的开发包,Android环境配置还是相对简单,像IOS这个封闭系统就比较难了。所以我实践了一个相对简单的方法去让各种平台不需要配置ROS开发环境就轻轻松松接入ROS内部网络。不过在进入正题之前还是要交代一些背景,下面是纯菜鸟的理解,请大牛多加批评指导~~~
一、什么是ROS机器人系统?
ROS是开源的,是用于机器人的一种后操作系统,或者说次级操作系统。它提供类似操作系统所提供的功能,包含硬件抽象描述、底层驱动程序管理、共用功能的执行、程序间的消息传递、程序发行包管理,它也提供一些工具程序和库用于获取、建立、编写和运行多机整合的程序。
额...很高级很难懂的样子~不如俺用非专业的草根语言描述一下:各种exe的通信桥梁。可能刚开始学ROS包括我在内的童鞋都会有点过分神化ROS系统,感觉ROS是万能的,什么都能做到。其实我觉得ROS也只是一种工具,对于一个使用ROS的项目来说,重点的不是在于ROS的使用技巧,而是怎么用算法处理从ROS里面得到的信息。换句话说就是数学。大部分高级的东西做到最后都是在搞数学。停住!我又说了很多废话了。。。
二、ROS机器人系统核心框架。
核心框架有三个主体:节点管理器、发布者和订阅者。节点管理器主要负责登记各种节点的信息以及作为它们之间通信的引导者。发布者和订阅者本身就是一个节点,都必须要在节点管理器去注册节点。发布者跟订阅者本身是没有耦合关系的,它们在建立连接之前是不知道双方的存在的。当一位订阅者要订阅一个主题的时候,节点管理器就会寻找有没有节点发布这个主题,如果找到了,节点管理器就会将发布者和订阅者关联起来,后面它们的收发信息是不会通过节点管理器的,而是直接P2P通信的。
额...还是有点不好理解?俺素一个俗人,就用一个比较俗的方法去解释上面那幅图是什么意思吧~~~
反正俺素从来没去过这些网站滴,不过俺大概猜得出它们的基本流程吧,就是说一男一女要征婚肯定要上那些网站注册个账号把,然后就留下自己的基本信息,世纪佳缘就帮他们拉线了,最后,那对男女各种聊,各种约会都不会经过中介的,大概就是那么一个意思。把下图跟上图一一对比就很容易理解上图的意思了。
三、ROS节点通信机制
其实ROS内部网络各种节点的通信都可以说是基于TCP/IP通信,只要在节点管理器注册一下,就可以跟各种节点进行通信了。这种通信方式使不同主机上的ROS节点有效地进行通信。
那么问题就来了,如果节点不是在Linux下平台的话怎么接入ROS内部的网络,获取内部的信息?前面也说过了,对于不同的平台,ROS是提供了相应的开发包。
Android平台:http://wiki.ros.org/android 缺点:不是支持所有的安卓版本的。
Windows平台:http://wiki.ros.org/win_ros 缺点:只支持桌面平台,不支持WP平台。最新的开发包只适用于旧版本的ros系统:fuerte\groovy\hydro,不支持indigo版本。
IOS平台: https://github.com/introlab/ros_for_ios 缺点:不是支持所有苹果版本,资料比较少。
针对上面的各种局限,俺提出一种非常简单的方法接入ROS内部网络,访问里面的信息。这种方法是不需要在其它平台配置ROS环境,只要能进行TCP/IP通信就行了,这个要求太低了。下面先说说实现的原理,其实实现的原理也是非常简单的,就是在ROS里面做一个TCP Sever代理节点,外部程序就可以通过这个代理节点访问到ROS内部网络了,哎,太简单了,地球人都能想到的方法!!!来到这里,大牛可以关闭窗口了,下面就是渣渣的实现过程了,没必要看了。
四、实现过程
在演示之前,首先说说我整个的开发环境:
系统:Ubuntu 14.04 LTS
ROS版本:Indigo
如果你跟我的环境一模一样的话,下面只要跟着我一步一步做就肯定可以的,因为我移植过很多台电脑的。
1、安装Qt。
既然要做一个代理服务器节点当然要考虑用什么去做,Qt是一个非常不错的选择,Indigo里面自带了Qt4.8.x的动态库(忘了),注意这是动态库,不是开发库,是编译不了qt程序的,所以我们需要安装一个qt的开发库,我选择了qt4.8.6,个人认为吧,qt5就没必要了,感觉跟indigo不太兼容。在Linux的qt都好像要自己编译安装的,所以为了节省大家的时间,直接用我编译的就行了:
https://yunpan.cn/cBnxHN8RCu9CG 访问密码 ffb0
(1)输入下面的命令,把我提供的压缩包解压到指定路径:
su #获取root权限 unzip Trolltech.zip -d /usr/local(2)添加环境变量,编辑~/.bashrc,添加下面的环境变量:
QTDIR=/usr/local/Trolltech/Qt-4.8.6 PATH=$QTDIR/bin:$PATH MANPATH=$QTDIR/doc/man:$MANPATH LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH export QTDIR PATH MANPATH LD_LIBRARY_PATH
编写ros版的qt程序需要ros开发包配合的,下载:https://yunpan.cn/cBn8TNx6DvpEv 访问密码 0459
上面是我自己修改过的,如果想看正式版的可以在这里下载:http://wiki.ros.org/qt_ros
下载下来解压后,我们只要碰/qt_ws/src/qt_tutorials里面的东西就行了,里面有两个demo,一个是android、另外一个是tcpServer,只要模仿这两个demo去编程就行了,跟普通Qt编程是没区别的,只是添加了一下ros的东西而已。由于这篇文章不是主要说qt和ros编程的,所以就不详细介绍这部分内容,有机会留到下一篇说一说。下面贴一下最主要的代码:
//talker.hpp
#ifndef TALKER_NODE_HPP_ #define TALKER_NODE_HPP_ /***************************************************************************** ** Includes *****************************************************************************/ #ifndef Q_MOC_RUN #include <ros/ros.h> #include "../common/qnode.hpp" #endif #include <string> /***************************************************************************** ** Class *****************************************************************************/ class TcpServer; class Talker : public QNode { Q_OBJECT public: Talker(int argc, char** argv); ~Talker(); void run(); void ros_comms_init(); private: ros::Publisher chatter_publisher; ros::ServiceClient add_client; TcpServer*server; public Q_SLOTS: void publish_msg(QString msg); }; #endif /* TALKER_NODE_HPP_ */
#include <ros/ros.h> #include <string> #include "talker.hpp" #include <std_msgs/String.h> #include <geometry_msgs/Twist.h> #include <sstream> #include "TcpServer.hpp" #include<std_srvs/Empty.h> /***************************************************************************** ** Implementation *****************************************************************************/ Talker::Talker(int argc, char** argv ) : QNode(argc,argv,"android_node") { on_init("http://localhost:11311", "127.0.0.1"); ROS_INFO("Android Node is starting!"); } Talker::~Talker() { if(server!=NULL) { delete server; server=NULL; } } void Talker::ros_comms_init() { ros::NodeHandle n; chatter_publisher = n.advertise<geometry_msgs::Twist>("turtle1/cmd_vel", 1000); add_client = n.serviceClient<std_srvs::Empty>("clear"); server=new TcpServer(6666,0); connect(server,SIGNAL(RECEVIEMESSAGE(QString)),this,SLOT(publish_msg(QString))); } void Talker::run() { ros::Rate loop_rate(1); while ( ros::ok() ) { ros::spinOnce(); loop_rate.sleep(); } std::cout << "Ros shutdown, proceeding to close the gui." << std::endl; if(server!=NULL) { server->deleteLater(); server=NULL; } Q_EMIT rosShutdown(); // used to signal the gui for a shutdown (useful to roslaunch) } void Talker::publish_msg(QString msg) { ROS_INFO("%s",msg.toStdString().c_str()); if(msg[0]!='I') { QStringList datas=msg.split(" "); int count=datas.count(); if(count==2) { geometry_msgs::Twist pose; pose.linear.x=datas[0].toInt(); pose.angular.z=datas[1].toInt(); chatter_publisher.publish(pose); }else if(count==1) { std_srvs::Empty srv; add_client.call(srv); } } }
3、实验部分
这次我开发了一个小小的安卓程序去接入ROS系统网络里面,去控制那只很经典的乌龟。ROS下的程序就在上面压缩包目录里面的android工程里面。
手机端开发源码: https://yunpan.cn/cBnMEKVyJpdiH 访问密码 7f7e
apk: https://yunpan.cn/cBnMSQGK7MCck 访问密码 57a4
使用方法:首先要编译一下qt程序,具体方法就不说了,然后启动ros后,启动android节点,再打开安卓程序,连接到服务器就可以对乌龟进行控制了。
后语:本文只是从Android平台上尝试了一下,当然其它平台也是没问题的,因为每个平台都有Socket编程,这个方法虽然不用折腾对应平台的ros开发包,但是因为必须在ros下建立一个qt代理服务端就显得有点麻烦。
参考资料:http://blog.csdn.net/hcx25909/article/details/8795043
标签:
原文地址:http://blog.csdn.net/trustguan/article/details/51922614