当前位置:   article > 正文

解决Rosbridge自定义action信息问题_roslib goal.on("result

roslib goal.on("result

前言:利用rosbridge开发一个网页版的action客户端。

一:rosbridge原理:

        rosbridge协议:该协议的基本思想是将节点间的分布式通信,改成“client节点”与一个代理节点进行C/S通信,然后代理节点再将请求转发给server节点,这样客户端就不需要实现整个ROS平台,只需要跟代理节点通信即可。

        网页上将发布的信息封装成json,通过websocket解析到代理节点,代理节点就可以转化为ros节点通信发布给Server端。

官方的rosbridge教程:rosbridge

ROSBridge简介以及理解使用博客:rosbridge

二、简单的examble分析:

网页实现部分代码:        

        第一部分:链接到两个roslib.js。官方提供的两个文件,用于链接到本地的websocket进行与ros交互。

  1. <script type="text/javascript" src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script>
  2. <script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script>

       第二部分:发布与订阅信息。

  1. /*向节点发送信息,创建一个topic,它的名字是'/position',,消息类型是'geometry_msgs/Twist'*/
  2. var cmdVel = new ROSLIB.Topic({
  3. ros : ros,
  4. name : '/position',
  5. messageType : 'geometry_msgs/Twist'
  6. });
  7. var twist = new ROSLIB.Message({
  8. linear : {
  9. x : 0.1,
  10. y : 0.2,
  11. z : 0.3
  12. },
  13. angular : {
  14. x : -0.1,
  15. y : -0.2,
  16. z : -0.3
  17. }
  18. });//创建一个message
  19. function func()//在点击”Publish”按钮后发布消息
  20. {
  21. cmdVel.publish(twist);//发布twist消息
  22. }
  23. /*从节点获取信息*/
  24. var listener = new ROSLIB.Topic({
  25. ros : ros,
  26. name : '/chatter',
  27. messageType : 'std_msgs/String'
  28. });
  29. //创建一个topic,它的名字是'/chatter',,消息类型是'std_msgs/String'
  30. function subscribe()//在点击”Subscribe”按钮后订阅'/chatter'的消息,并将其显示到网页中
  31. {
  32. listener.subscribe(function(message) {
  33. document.getElementById("output").innerHTML = ('Received message on ' + listener.name + ': ' + message.data);
  34. });
  35. }

本地启动websocket代理节点,监听来自端口的信息,再启动server节点就可以通信:

$roslaunch rosbridge_server rosbridge_websocket.launch

总结:上面的通信方式就是简单的topic通信。没有自定义信息内容。使用的都是官方提供的信息格式:geometry_msgs/Twist和std_msgs/String。

二:问题描述:官方提供的rosbridge的action通信实例:

        代码如下(只看定义消息部分代码,完整代码附录)

  1. var fibonacciClient = new ROSLIB.ActionClient({
  2. ros : ros,
  3. serverName : '/fibonacci',
  4. actionName : 'actionlib_tutorials/FibonacciAction'
  5. });
  6. var goal = new ROSLIB.Goal({
  7. actionClient : fibonacciClient,
  8. goalMessage : {
  9. order : 7
  10. }
  11. });
  12. goal.on('feedback', function(feedback) {
  13. console.log('Feedback: ' + feedback.sequence);
  14. });
  15. goal.on('result', function(result) {
  16. console.log('Final Result: ' + result.sequence);
  17. });
  18. goal.send();
  19. </html>

问题:这个action的消息定义是'actionlib_tutorials/FibonacciAction'。也是直接能被识别的消息格式。现在的问题是:如何在网页使用自定义的action消息?

       方案一: 因为网页是不识别头文件的,js和c++也是完全两种语言。我需要找到官方的消息定义在什么位置?如何定义的?

        网页上链接的这两个js并没有消息自定义。但是在官方提供的rosbridge_server包的library文件夹下里有很多消息定义的功能包:如图:

  1. ├── CHANGELOG.rst
  2. ├── CMakeLists.txt
  3. ├── msg #定义消息
  4. │ ├── Num.msg #定义数字消息
  5. │ ├── TestChar.msg #定义字符消息
  6. │ ├── TestDurationArray.msg #定义Duration数组消息
  7. │ ├── TestHeaderArray.msg #定义Header数组消息
  8. │ ├── TestHeader.msg #定义Header消息
  9. │ ├── TestHeaderTwo.msg #定义Header消息
  10. │ ├── TestTimeArray.msg #定义Time数组消息
  11. │ ├── TestUInt8FixedSizeArray16.msg #定义Unit8[16]消息
  12. │ └── TestUInt8.msg #定义Unit8[]消息
  13. ├── package.xml
  14. ├── setup.py #python安装脚本
  15. ├── src
  16. │ └── rosbridge_library #核心库
  17. │ ├── capabilities #功能包
  18. │ │ ├── advertise.py #执行话题的广播和取消
  19. │ │ ├── advertise_service.py #执行服务的广播
  20. │ │ ├── call_service.py #调用服务
  21. │ │ ├── defragmentation.py #对消息内容解析
  22. │ │ ├── fragmentation.py #对消息内容封装
  23. │ │ ├── __init__.py #声明为Python库
  24. │ │ ├── publish.py #发布话题
  25. │ │ ├── service_response.py #服务反馈处理
  26. │ │ ├── subscribe.py #订阅话题
  27. │ │ └── unadvertise_service.py #取消服务广播
  28. │ ├── capability.py
  29. │ ├── __init__.py
  30. │ ├── internal #内部功能实现
  31. │ │ ├── exceptions.py #异常处理
  32. │ │ ├── __init__.py
  33. │ │ ├── message_conversion.py #消息转换
  34. │ │ ├── pngcompression.py #图像压缩
  35. │ │ ├── publishers.py #跟踪使用特定发布者的客户端。提供用于发布消息和注册使用这个发布者的客户端的API
  36. │ │ ├── ros_loader.py #ros相关核心类导入
  37. │ │ ├── services.py #为特定的服务创建服务调用者,使用start()开启独立线程,或在线程中使用run()函数。
  38. │ │ ├── subscribers.py #管理和与ROS订阅服务器对象接口.单个订阅者在多个客户端之间共享
  39. │ │ ├── subscription_modifiers.py #位于来自订阅的传入消息和传出消息之间发布方法,提供限制/缓冲功能.当参数改变时,处理程序可以转换到不同的类型的处理程序
  40. │ │ └── topics.py #发布者和订阅者共同的代码和异常处理
  41. │ ├── protocol.py #单个客户端与ROS交互的接口.
  42. │ ├── rosbridge_protocol.py #继承protocol协议,初始化rosbridge功能列表
  43. │ └── util
  44. │ └── __init__.py
  45. ├── srv #服务定义
  46. │ ├── AddTwoInts.srv #
  47. │ ├── SendBytes.srv #发送内容定义
  48. │ ├── TestArrayRequest.srv
  49. │ ├── TestEmpty.srv
  50. │ ├── TestMultipleRequestFields.srv
  51. │ ├── TestMultipleResponseFields.srv
  52. │ ├── TestNestedService.srv
  53. │ ├── TestRequestAndResponse.srv
  54. │ ├── TestRequestOnly.srv
  55. │ └── TestResponseOnly.srv
  56. └── test #相关测试,包括核心功能,扩展功能,内部执行

目前想到的就是找到弄清楚官方的定义方式,然后学着自定义action。

进展:首先自定义好action信息头文件。在工作空间下实现Cient节点和Servery节点之间的action通信。

        其次,将html文件里的消息定义为自定义的消息格式:如下:

  1. var Client = new ROSLIB.ActionClient({
  2. ros : ros,
  3. serverName : 'oms_client',
  4. actionName : 'oms/SendCommandAction'
  5. });
  6. var goal = new ROSLIB.Goal({
  7. actionClient : Client,
  8. goalMessage : {
  9. request :{
  10. head:{source :"oms",target :"vr"},
  11. subject : "UR",
  12. action :"moveto",
  13. actionData : "111",
  14. qualifierData:"2222"
  15. }
  16. //request : oms
  17. }
  18. });

接着实现html网页通过websocket与Server节点的通信。

方案二:拆分action通信为基本通信方式。(备用,最好是自定义使用action通信)

方案三:使用rosbridge进行简单通讯,在服务期上写自定义的发送信息的节点。由web对服务器上的节点进行命令执行。

更多详细action,请参考官网教程

action代码附录:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <script src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.js"></script>
  6. <script src="http://static.robotwebtools.org/roslibjs/current/roslib.js"></script>
  7. <script>
  8. var ros = new ROSLIB.Ros({
  9. url : 'ws://localhost:9090'
  10. });
  11. var fibonacciClient = new ROSLIB.ActionClient({
  12. ros : ros,
  13. serverName : '/fibonacci',
  14. actionName : 'actionlib_tutorials/FibonacciAction'
  15. });
  16. var goal = new ROSLIB.Goal({
  17. actionClient : fibonacciClient,
  18. goalMessage : {
  19. order : 7
  20. }
  21. });
  22. goal.on('feedback', function(feedback) {
  23. console.log('Feedback: ' + feedback.sequence);
  24. });
  25. goal.on('result', function(result) {
  26. console.log('Final Result: ' + result.sequence);
  27. });
  28. ros.on('connection', function() {
  29. console.log('Connected to websocket server.');
  30. });
  31. ros.on('error', function(error) {
  32. console.log('Error connecting to websocket server: ', error);
  33. });
  34. ros.on('close', function() {
  35. console.log('Connection to websocket server closed.');
  36. });
  37. goal.send();
  38. </script>
  39. </head>
  40. <body>
  41. <h1>Fibonacci ActionClient Example</h1>
  42. <p>Check the Web Console for output</p>
  43. </body>
  44. </html>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/107766
推荐阅读
相关标签
  

闽ICP备14008679号