赞
踩
前言:利用rosbridge开发一个网页版的action客户端。
rosbridge协议:该协议的基本思想是将节点间的分布式通信,改成“client节点”与一个代理节点进行C/S通信,然后代理节点再将请求转发给server节点,这样客户端就不需要实现整个ROS平台,只需要跟代理节点通信即可。
网页上将发布的信息封装成json,通过websocket解析到代理节点,代理节点就可以转化为ros节点通信发布给Server端。
官方的rosbridge教程:rosbridge
ROSBridge简介以及理解使用博客:rosbridge
网页实现部分代码:
第一部分:链接到两个roslib.js。官方提供的两个文件,用于链接到本地的websocket进行与ros交互。
<script type="text/javascript" src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script> <script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script>第二部分:发布与订阅信息。
/*向节点发送信息,创建一个topic,它的名字是'/position',,消息类型是'geometry_msgs/Twist'*/ var cmdVel = new ROSLIB.Topic({ ros : ros, name : '/position', messageType : 'geometry_msgs/Twist' }); var twist = new ROSLIB.Message({ linear : { x : 0.1, y : 0.2, z : 0.3 }, angular : { x : -0.1, y : -0.2, z : -0.3 } });//创建一个message function func()//在点击”Publish”按钮后发布消息 { cmdVel.publish(twist);//发布twist消息 } /*从节点获取信息*/ var listener = new ROSLIB.Topic({ ros : ros, name : '/chatter', messageType : 'std_msgs/String' }); //创建一个topic,它的名字是'/chatter',,消息类型是'std_msgs/String' function subscribe()//在点击”Subscribe”按钮后订阅'/chatter'的消息,并将其显示到网页中 { listener.subscribe(function(message) { document.getElementById("output").innerHTML = ('Received message on ' + listener.name + ': ' + message.data); }); }本地启动websocket代理节点,监听来自端口的信息,再启动server节点就可以通信:
$roslaunch rosbridge_server rosbridge_websocket.launch
总结:上面的通信方式就是简单的topic通信。没有自定义信息内容。使用的都是官方提供的信息格式:geometry_msgs/Twist和std_msgs/String。
二:问题描述:官方提供的rosbridge的action通信实例:
代码如下(只看定义消息部分代码,完整代码附录)
- var fibonacciClient = new ROSLIB.ActionClient({
- ros : ros,
- serverName : '/fibonacci',
- actionName : 'actionlib_tutorials/FibonacciAction'
- });
-
- var goal = new ROSLIB.Goal({
- actionClient : fibonacciClient,
- goalMessage : {
- order : 7
- }
- });
-
- goal.on('feedback', function(feedback) {
- console.log('Feedback: ' + feedback.sequence);
- });
-
- goal.on('result', function(result) {
- console.log('Final Result: ' + result.sequence);
- });
-
- goal.send();
-
- </html>
问题:这个action的消息定义是'actionlib_tutorials/FibonacciAction'。也是直接能被识别的消息格式。现在的问题是:如何在网页使用自定义的action消息?
方案一: 因为网页是不识别头文件的,js和c++也是完全两种语言。我需要找到官方的消息定义在什么位置?如何定义的?
网页上链接的这两个js并没有消息自定义。但是在官方提供的rosbridge_server包的library文件夹下里有很多消息定义的功能包:如图:
├── CHANGELOG.rst ├── CMakeLists.txt ├── msg #定义消息 │ ├── Num.msg #定义数字消息 │ ├── TestChar.msg #定义字符消息 │ ├── TestDurationArray.msg #定义Duration数组消息 │ ├── TestHeaderArray.msg #定义Header数组消息 │ ├── TestHeader.msg #定义Header消息 │ ├── TestHeaderTwo.msg #定义Header消息 │ ├── TestTimeArray.msg #定义Time数组消息 │ ├── TestUInt8FixedSizeArray16.msg #定义Unit8[16]消息 │ └── TestUInt8.msg #定义Unit8[]消息 ├── package.xml ├── setup.py #python安装脚本 ├── src │ └── rosbridge_library #核心库 │ ├── capabilities #功能包 │ │ ├── advertise.py #执行话题的广播和取消 │ │ ├── advertise_service.py #执行服务的广播 │ │ ├── call_service.py #调用服务 │ │ ├── defragmentation.py #对消息内容解析 │ │ ├── fragmentation.py #对消息内容封装 │ │ ├── __init__.py #声明为Python库 │ │ ├── publish.py #发布话题 │ │ ├── service_response.py #服务反馈处理 │ │ ├── subscribe.py #订阅话题 │ │ └── unadvertise_service.py #取消服务广播 │ ├── capability.py │ ├── __init__.py │ ├── internal #内部功能实现 │ │ ├── exceptions.py #异常处理 │ │ ├── __init__.py │ │ ├── message_conversion.py #消息转换 │ │ ├── pngcompression.py #图像压缩 │ │ ├── publishers.py #跟踪使用特定发布者的客户端。提供用于发布消息和注册使用这个发布者的客户端的API │ │ ├── ros_loader.py #ros相关核心类导入 │ │ ├── services.py #为特定的服务创建服务调用者,使用start()开启独立线程,或在线程中使用run()函数。 │ │ ├── subscribers.py #管理和与ROS订阅服务器对象接口.单个订阅者在多个客户端之间共享 │ │ ├── subscription_modifiers.py #位于来自订阅的传入消息和传出消息之间发布方法,提供限制/缓冲功能.当参数改变时,处理程序可以转换到不同的类型的处理程序 │ │ └── topics.py #发布者和订阅者共同的代码和异常处理 │ ├── protocol.py #单个客户端与ROS交互的接口. │ ├── rosbridge_protocol.py #继承protocol协议,初始化rosbridge功能列表 │ └── util │ └── __init__.py ├── srv #服务定义 │ ├── AddTwoInts.srv # │ ├── SendBytes.srv #发送内容定义 │ ├── TestArrayRequest.srv │ ├── TestEmpty.srv │ ├── TestMultipleRequestFields.srv │ ├── TestMultipleResponseFields.srv │ ├── TestNestedService.srv │ ├── TestRequestAndResponse.srv │ ├── TestRequestOnly.srv │ └── TestResponseOnly.srv └── test #相关测试,包括核心功能,扩展功能,内部执行目前想到的就是找到弄清楚官方的定义方式,然后学着自定义action。
进展:首先自定义好action信息头文件。在工作空间下实现Cient节点和Servery节点之间的action通信。
其次,将html文件里的消息定义为自定义的消息格式:如下:
-
- var Client = new ROSLIB.ActionClient({
- ros : ros,
- serverName : 'oms_client',
- actionName : 'oms/SendCommandAction'
- });
-
- var goal = new ROSLIB.Goal({
- actionClient : Client,
- goalMessage : {
- request :{
- head:{source :"oms",target :"vr"},
- subject : "UR",
- action :"moveto",
- actionData : "111",
- qualifierData:"2222"
- }
-
- //request : oms
- }
- });
接着实现html网页通过websocket与Server节点的通信。
方案二:拆分action通信为基本通信方式。(备用,最好是自定义使用action通信)
方案三:使用rosbridge进行简单通讯,在服务期上写自定义的发送信息的节点。由web对服务器上的节点进行命令执行。
更多详细action,请参考官网教程
action代码附录:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <script src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.js"></script>
- <script src="http://static.robotwebtools.org/roslibjs/current/roslib.js"></script>
-
- <script>
- var ros = new ROSLIB.Ros({
- url : 'ws://localhost:9090'
- });
-
- var fibonacciClient = new ROSLIB.ActionClient({
- ros : ros,
- serverName : '/fibonacci',
- actionName : 'actionlib_tutorials/FibonacciAction'
- });
-
- var goal = new ROSLIB.Goal({
- actionClient : fibonacciClient,
- goalMessage : {
- order : 7
- }
- });
-
- goal.on('feedback', function(feedback) {
- console.log('Feedback: ' + feedback.sequence);
- });
-
- goal.on('result', function(result) {
- console.log('Final Result: ' + result.sequence);
- });
-
- ros.on('connection', function() {
- console.log('Connected to websocket server.');
- });
-
- ros.on('error', function(error) {
- console.log('Error connecting to websocket server: ', error);
- });
-
- ros.on('close', function() {
- console.log('Connection to websocket server closed.');
- });
-
- goal.send();
- </script>
- </head>
-
- <body>
- <h1>Fibonacci ActionClient Example</h1>
- <p>Check the Web Console for output</p>
- </body>
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。