< >
Home » ROS与Web入门教程 » ROS与web入门教程-控制turtlebot3建图

ROS与web入门教程-控制turtlebot3建图

ROS与web入门教程-控制turtlebot3建图

说明:

  • 介绍如何通过页面控制turtlebot3建图

步骤:

  • 增加新的模板slam2d.php
cd /home/ubuntu/web/cms/templates/Pages
cp ros.php slam2d.php
  • 内容如下:
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link      https://cakephp.org CakePHP(tm) Project
 * @since     0.10.0
 * @license   https://opensource.org/licenses/mit-license.php MIT License
 * @var \App\View\AppView $this
 */
use Cake\Cache\Cache;
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Datasource\ConnectionManager;
use Cake\Error\Debugger;
use Cake\Http\Exception\NotFoundException;

$this->disableAutoLayout();

?>
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />

    <script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/nipplejs/0.7.3/nipplejs.js"></script>
    <?= $this->Html->script('https://static.robotwebtools.org/EaselJS/current/easeljs.js') ?>
    <?= $this->Html->script('https://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js') ?>
    
    <?= $this->Html->script('ros2d.js') ?>
    <?= $this->fetch('script') ?>
<script type="text/javascript" type="text/javascript">
        var ros = new ROSLIB.Ros({
            url: 'ws://192.168.0.139:9090'
        });

        ros.on('connection', function() {
            document.getElementById("status").innerHTML = "Connected";
        });

        ros.on('error', function(error) {
            document.getElementById("status").innerHTML = "Error";
        });

        ros.on('close', function() {
            document.getElementById("status").innerHTML = "Closed";
        });

        var txt_listener = new ROSLIB.Topic({
            ros: ros,
            name: '/cmd_vel',
            messageType: 'geometry_msgs/Twist'
        });

        txt_listener.subscribe(function(m) {
            document.getElementById("msg_x").innerHTML = m.linear.x;
            document.getElementById("msg_y").innerHTML = m.angular.z;
            //move(1, 0);
        });

        cmd_vel_listener = new ROSLIB.Topic({
            ros: ros,
            name: "/cmd_vel",
            messageType: 'geometry_msgs/Twist'
        });

        move = function(linear, angular) {
            var twist = new ROSLIB.Message({
                linear: {
                    x: linear,
                    y: 0,
                    z: 0
                },
                angular: {
                    x: 0,
                    y: 0,
                    z: angular
                }
            });
            cmd_vel_listener.publish(twist);
        }

        createJoystick = function() {
            var options = {
                zone: document.getElementById('zone_joystick'),
                threshold: 0.1,
                position: {
                    left: 50 + '%'
                },
                mode: 'static',
                size: 150,
                color: '#000000',
            };
            manager = nipplejs.create(options);

            linear_speed = 0;
            angular_speed = 0;

            manager.on('start', function(event, nipple) {
                timer = setInterval(function() {
                    move(linear_speed, angular_speed);
                }, 25);
            });

            manager.on('move', function(event, nipple) {
                max_linear = 0.22; // m/s
                max_angular = 2.0; // rad/s
                max_distance = 75.0; // pixels;
                linear_speed = Math.sin(nipple.angle.radian) * max_linear * nipple.distance / max_distance;
                angular_speed = -Math.cos(nipple.angle.radian) * max_angular * nipple.distance / max_distance;
            });

            manager.on('end', function() {
                if (timer) {
                    clearInterval(timer);
                }
                self.move(0, 0);
            });
        }
        window.onload = function() {
            createJoystick();
            init();
        }

            /**
         * Setup all visualization elements when the page is loaded. 
         */
        function init() {

            // Create the main viewer.
            var viewer = new ROS2D.Viewer({
                divID: 'map',
                width: 308,
                height: 250
            });

            // Setup the map client.
            var gridClient = new ROS2D.OccupancyGridClient({
                ros: ros,
                rootObject: viewer.scene
            });
            // Scale the canvas to fit to the map
            gridClient.on('change', function() {
                viewer.scaleToDimensions(gridClient.currentGrid.width, gridClient.currentGrid.height);
                viewer.shift(gridClient.currentGrid.pose.position.x, gridClient.currentGrid.pose.position.y);
            });
        }
    </script>
</head>

<body >
    <h1>Simple ROS User Interface</h1>
    <p>Connection status: <span id="status"></span></p>
    <p>Last message on X <span id="msg_x"></span></p>
    <p>Last message on Y <span id="msg_y"></span></p>
    <div id="zone_joystick" style="position: relative;"></div>
    <div id="map"></div>
</body>

</html>
  • 增加虚拟圆盘控制器
  • 增加X,Y速度的显示
  • 显示地图,非实时,移动需要刷新,加载新地图

测试:

  • 运行gazebo
roslaunch turtlebot3_gazebo turtlebot3_world.launch
  • 运行建图
roslaunch turtlebot3_slam turtlebot3_slam.launch slam_methods:=gmapping
  • 运行rosbridge_server
roslaunch rosbridge_server rosbridge_websocket.launch
  • 打开页面:http://192.168.0.139/pages/slam2d
  • 效果如下:

请输入图片描述

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ros与web入门教程