我的AI之路(26)--使用ROSBridge WebSocket和roslibjs构建一个简单的控制机器人的web demo

13 篇文章 11 订阅
3 篇文章 3 订阅

     在一个复杂的机器人后端控制平台系统开发完成以前,往往需要对你的机器人产品进行简单的软件架构设计验证或进行控制测试,这时,如果能花比较少的时间快速做一个web页面或者一个Android app来作此用途的话能节省不少人力,本人花比较少的时间做了一个web demo和几个安卓app用于不同机器人的通讯和控制的验证和测试,先只说怎么做web demo,实现安卓app的思路跟基于Java EE开发机器人控制平台的思路比较相似,关键技术是使用Java WebSocket建立与机器人上的Rosbridge之间的双向长连接和实现自定义的应用协议与rosbridge v2.0 Protocol 之间的转换来实现应用和ROS通讯的解耦合,就先不说了,后面有空再说,先只说说怎么做一个简单的web demo。

    前面说过,ROSBridge提供了使用tcp/udp/websocket连接调用机器人上的ROS来实现对机器人的控制的途径,ROSBridge提供了WebSocket Server可以连接,那么写一个web页面使用websocket连接到Rosbridge遵循rosbridge v2.0 Protocol 与ROS进行交互就可以控制机器人了,roslibjs就是个可以用于此目的工具库,roslibjs是ROS JavaScript库,看它的源码就知道,实际上它的下层就是使用websocket与Rosbridge进行通讯,写过JavaScript的对ROS有一定了解后可以用它很快实现一个页面来控制机器人,另外,如果页面中如果还需要有2D、3D可视化效果的话,还需要用到ros2djs和ros3djs,此外还需要用到一些相关javascript支持库。

    具体步骤:

    1.首先当然得安装rosbridge:

      sudo apt-get install ros-kinetic-rosbridge-suite

     2.获取相关JavaScript库(http://robotwebtools.org/tools.html#libraries只提供了一部分,我把收集到的这些js库和引用到的相关css文件打包上传到这里了,设置了5积分下载为防恶意访问):

      获取roslib.js,ros3d.min.js,ros2d.min.js(也可以从https://static.robotwebtools.org下载)

      git clone https://github.com/RobotWebTools/roslibjs.git

      git clone https://github.com/RobotWebTools/ros2djs.git

      git clone https://github.com/RobotWebTools/ros3djs.git

       把下面这些js文件下载到本地并且与roslib.js、ros3d.min.js,ros2d.min.js放到同一个目录scripts下供稍后web页面使用:

       https://static.robotwebtools.org/threejs/current/three.js
       https://static.robotwebtools.org/threejs/current/ColladaLoader.js
       https://static.robotwebtools.org/threejs/current/STLLoader.js
       https://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js
       https://static.robotwebtools.org/roslibjs/current/roslib.js

       https://static.robotwebtools.org/ros2djs/current/ros2d.min.js
       https://static.robotwebtools.org/ros3djs/current/ros3d.min.js
       https://static.robotwebtools.org/keyboardteleopjs/current/keyboardteleop.js

       https://github.com/rctoris/mjpegcanvasjs/blob/develop/src/MjpegCanvas.js

       另外:https://github.com/mrdoob/three.js 这里可以找到JavaScript 3D的全部js文件。

       roslib.js,ros2d.js,ros3d.js的API可以这里查:

        roslibjs APIs: http://robotwebtools.org/jsdoc/roslibjs/current/
        ros2djs APIs: http://robotwebtools.org/jsdoc/ros2djs/current/
        ros3djs APIs: http://robotwebtools.org/jsdoc/ros3djs/current/

    3.如果需要用到模拟视频监控,还需下载和编译安装一个支持HTTP streaming of ROS
images的web_video_server包:

      cd ~/catkin_ws/src

      git clone https://github.com/RobotWebTools/web_video_server.git

      cd ..

      catkin_make

     4. 主要代码 (可以参考<<ROS Robotics Projects>>一书的第12章对应的html源码,尤其可以在speechcommands.html的基础上修改,不过要注意的是,speech_commands示例代码已被作者早就从https://github.com/qboticslabs/ros_robotics_projects上删除,需要从历史版本中下载,事实上这个上面的不少代码都已经不能直接使用,因为有些文件或者引用的文件都找不着了,需要自己想办法琢磨解决错误,所以仅供参考,下载后恐怕多半跑不起来 :) 。此外,可以参考这个: https://github.com/UbiquityRobotics/speech_commands):

        (1)包含用到的js和css:

           <link rel="stylesheet" type="text/css" href="scripts/jquery-ui.css"/>
          <link rel="stylesheet" type="text/css" href="scripts/bootstrap.min.css"/>
          <link rel="stylesheet" type="text/css" href="scripts/font-awesome.min.css"/>

          ...

          <script type="text/javascript" src="scripts/jquery.min.js"></script>
         <script type="text/javascript" src="scripts/bootstrap.min.js"></script>
         <script type="text/javascript" src="scripts/jquery-ui.min.js"></script>
         <script type="text/javascript" src="scripts/eventemitter2.min.js"></script>
         <script type="text/javascript" src="scripts/roslib.min.js"></script> 
         <script type="text/javascript" src="scripts/bootbox.min.js"></script>
         <script type="text/javascript" src="scripts/three.js"></script>
         <script type="text/javascript" src="scripts/ColladaLoader.js"></script>
        <script type="text/javascript" src="scripts/STLLoader.js"></script>
        <script type="text/javascript" src="scripts/ColladaLoader2.js"></script>
        <script type="text/javascript" src="scripts/ros3d.min.js"></script>
        <script type="text/javascript" src="scripts/mjpegcanvas.js"></script>
        <script type="text/javascript" src="scripts/keyboardteleop.js"></script>

      (2) 对speech_commands.html做的主要修改(改变连接控制和增加了3D可视化控件):

        function connect() {
            var connectButton;

            if (connected) {            // disconnect
                ros.close();
            } else {
                if(hasEverConected){
                   bootbox.alert ("请刷新页面后再连接!");  //因为roslibjs和ros3djs没有资源管理和释放功能,所以不得不这么限制!否则每次连接页面会重复创建Viewer object!
                   return;
                }
                robotUrl = document.getElementById("robotUrlEntry").value.trim();
                if (robotUrl == '') {
                    bootbox.alert ("请输入URL和port");
                    return;
                }
                robotUrl = robotUrl.replace("https:", "wss:");
                robotUrl = robotUrl.replace("http:", "ws:");
                if ((robotUrl.slice (0,5) != "wss://") && (robotUrl.slice (0,4) != "ws://") &&
                        (robotUrl.charAt(robotUrl.length - 5) != ":")) {
                
                    var r = bootbox.alert 
                        ("URL应该以http, https, ws或wss开头, 并以端口结尾, 例如 ':9090'.");
                        return;
                }

                ros = new ROSLIB.Ros({    // Connecting to ROS.
                    url: robotUrl                             
                }); 

                //创建可视化控件
                ip = location.hostname;
                if(ip=="")ip="localhost";
                res_path= "http://"+ip+"/share";

                if(!hasEverConected)
                {            

                    viewer = new ROS3D.Viewer({
                      background : 000,
                      divID : 'urdf',
                      //width : 1280,
                      //height : 600,
                      width : 800,
                      height : 400,
                      antialias : true

                    });
                 
                    // Add a grid.
                    viewer.addObject(new ROS3D.Grid());
                    
                   // Create the Stream viewer.
                    streamViewer = new MJPEGCANVAS.MultiStreamViewer({
                      divID : 'mjpeg',
                      host : 'localhost',
                      width : 800,
                      height : 400,
                      host : ip,
                      port : 8080,
                      interval : 200,
                      topics : [ '/camera/rgb/image_raw', '/camera/rgb/image_raw',
                      '/camera/rgb/image_raw' ],
                      labels : [ 'Robot View', 'Left Arm View', 'Right Arm View' ]

                    });

                 hasEverConected=true;
               }
             
            // Setup a client to listen to TFs.
            tfClient = new ROSLIB.TFClient({
                      ros : ros,
                      fixedFrame : base_frame,
                      angularThres : 0.01,
                      transThres : 0.01,
                      rate : 10.0
                    });

                // Setup the URDF client.                  
             urdfClient = new ROS3D.UrdfClient({
                      ros : ros,
                      tfClient : tfClient,
                      //path : 'http://resources.robotwebtools.org/',
                      path : res_path,
                      rootObject : viewer.scene,
                      loader : ROS3D.COLLADA_LOADER
                    });
                             
            // Initialize the teleop.
             teleop = new KEYBOARDTELEOP.Teleop({
                      ros : ros,
                      topic : teleop_topic
                    });

                  
        } //else

            ros.on('connection', function() {
                    localStorage.robotUrl = robotUrl;
                    connectButton = document.getElementById("connectButton");
                    connectButton.innerHTML = "断开";
                    connectButton.style.background="#00cc00";            // green
                    say ('connected');
                    connected = true;
                    console.log ('Connected to websocket server.');
                });

            ros.on('error', function(error) {
                 console.log (error);
                 bootbox.alert ('Error connecting to websocket server. ');
            });

            ros.on('close', function() {
                if (connected) {            // throw away a second call
                    connected = false;
                    connectButton = document.getElementById("connectButton");
                    connectButton.style.background = "#006dcc";    
                    connectButton.innerHTML = "连接"
                    say ('connection closed');   
                    console.log('Connection to websocket server closed.');
                }
            });

        } //function connect()    

    4.需要用到3D可视化效果,那么还需要安装tf2_web_republisher,tf2_web_republisher的作用是计算TF数据并通过rosbridge_server发给ros3djs client(ROSLIB.TFClient 实例),ROSLIB.TFClient对象订阅来自tf2_web_republisher的TF数据并更新ROS3D.Viewer对象,ROS3D.Viewer对象将URDF model在浏览器里可视化:

       cd ~/catkin_ws/src
       git clone https://github.com/RobotWebTools/tf2_web_republisher
       sudo apt-get install ros-kinetic-tf2-ros
       cd ~/catkin_ws
       catkin_make

    5.页面里用到3D效果,如果urdf文件也放在机器人上(或者模拟机器人所在的Linux服务器上):

         var urdfClient = new ROS3D.UrdfClient({
            ros : ros,
            tfClient : tfClient,
            path : 'http://localhost/share',
            rootObject : viewer.scene,
            loader : ROS3D.COLLADA_LOADER
          });

      那么还需安装个http sever,比如安装apache,下面是安装apache2并修改配置和启动:

       sudo apt-get install apache2

       #把urdf所在的文件夹share通过链接放到apache的顶级目录下

       ln -s /opt/ros/kinetic/share /var/www/html

       cd /etc/apache2
       vi apache2.conf 

       #做如下修改:

       <Directory /var/www/>
         Options Indexes FollowSymLinks
         AllowOverride None
         Require all granted
         Header set Access-Control-Allow-Origin http://localhost/share
      </Directory>

       #Enabling module headers. otherwise, "Invalide command Header" will be seen when you starting apache2.service

       sudo a2enmod headers

       #start apache   

       systemctl restart apache2.service

       

     如果apache里不做上面的Allow-Control-Allow-Origin设置,会报跨域访问错误:

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/share/turtlebot_description/meshes/stacks/hexagons/pole_bottom.dae. (Reason: CORS request did not succeed).

    做了上面的改动后,Firefox可以了,但Chrome浏览器还不行, 需下载最新谷歌跨域扩展插件,在谷歌浏览器输入:chrome://extensions,然后把下载好的文件拖入chrome://extensions页面,点击安装即可完成安装;不需要特殊设置,就可以完成跨域请求了。

   6. 启动仿真机器人及相关节点和Server的命令:

      roslaunch turtlebot_gazebo turtlebot_world.launch
      rosrun web_video_server web_video_server
      rosrun tf2_web_republisher tf2_web_republisher
      roslaunch rosbridge_server rosbridge_websocket.launch

   7.拷贝demo目录(在speech_commands包上做的修改:补齐了原来缺失的js文件和根据需要修改或增加了speech_commands.html的代码)到apache下并访问它:

      cp -rf demo /var/www/html

      #假设仿真机器人所在的服务器的IP是192.168.1.133,在浏览器里输入下面的地址即可打开demo并操控机器人

      http://192.168.1.133/demo/demo.html

      

      

  • 12
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 37
    评论
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arnold-FY-Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值