Удаленное управление Turtlebot через браузер джойстиком, голосом, с помощью Kinect. Часть 4


Продолжение. Начало — Часть 1, Часть 2 и Часть 3.

В этой части рассмотрим управление Turtlebot через браузер с помощью джойстика.

Библиотека Gamepad.js
Поддержка браузерами джойстиков находится на начальном этапе развития. Во-первых из браузеров поддерживают Ghrome и Firefox — ночные сборки. Во-вторых, далеко не все джойстики. Наилучшие результаты с проводным XBox-360. У меня в наличии Defender Gamne Racer X7, который может работать в двух режимах, один из которых HID-устройство, другой — контроллер XBOX360 . Переключение производится с помощью кнопки Mode.

Есть библиотека gamepad.js, я брал здесь, пришлось переделывать.
Вот код gamepad.html (добавляем в speech.html функционал для джойстика)

<html>
<head>
<script src='ros.js'></script>
<script src='gamepad.js'></script>
<script type="text/javascript">

var Item = function() {
        this.button1 = 0.0;
        this.button2 = 0.0;
        this.button3 = 0.0;
        this.button4 = 0.0;
        this.button5 = 0.0;
        this.button6 = 0.0;
        this.button7 = 0.0;
        this.button8 = 0.0;
        this.button9 = 0.0;
        this.button10 = 0.0;
        this.button11 = 0.0;
        this.button12 = 0.0;
        this.button13 = 0.0;
        this.button14 = 0.0;
        this.button15 = 0.0;
        this.button16 = 0.0;
        this.axes1 = 0.0;
        this.axes2 = 0.0;
        this.axes3 = 0.0;
        this.axes4 = 0.0;
    };

var choice_robot="192.168.1.103";
var con = new Bridge("ws://192.168.1.103:9090");

var get_data2=function(msg)
  {
   var voltage=parseInt(msg/65535*100);
      document.getElementById("battery").innerHTML=voltage+" %";
    if(voltage>70)
      document.getElementById("battery").style.backgroundColor='green';
    else if(voltage>30)
      document.getElementById("battery").style.backgroundColor='yellow';
    else
      document.getElementById("battery").style.backgroundColor='red';
  }
con.onOpen=function()
  {
  var cback2=function(msg2) {JSON.stringify(msg2),get_data2(msg2.voltage);}
    con.subscribe(cback2,'/turtlebot_node/sensor_state','turtlebot_node/TurtlebotSensorState');
    con.advertise('/turtlebot_servo', 'std_msgs/Int16');	
  }

function main() { 
   document.getElementById('button2').addEventListener('click', function(e) {send_ros1(); }, true);
   document.getElementById('button2').addEventListener('click', function(e) {send_ros2(); }, true);
   }
    //  джойстик
function joystick_actions(res)
  {
  document.getElementById("res").value=res;
  document.getElementById('button1').click();
  return;
  }    function send_ros1() {
        //alert("send");
        switch(parseInt(document.getElementById("res").value))
          {
          // стоп
          case 9: go_poz[0]=0;go_poz[5]=0;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
            break;
          // движение turtlebot
          case 13: go_poz[0]=1;go_poz[5]=0;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
            break;
          case 14: go_poz[0]=-1;go_poz[5]=0;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
             break;
          case 15: go_poz[5]=-1;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
             break;
          case 16: go_poz[5]=1;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
             break;
          // движение камеры 
          // джойстик1 - вверх-вниз
          // джойстик2 - влево-вправо
          case 17: var p3=Math.round((Item.axes3+1)*90);
                   var p2=Math.round((Item.axes2+1)*90);
                   con.publish('/turtlebot_servo', {'data':p3*256+p2});
            break;
          case 18: var p3=Math.round((Item.axes3+1)*90);
                   var p2=Math.round((Item.axes2+1)*90);
                   con.publish('/turtlebot_servo', {'data':p3*256+p2});
            break;
          case 19: var p3=Math.round((Item.axes3+1)*90);
                   var p2=Math.round((Item.axes2+1)*90);
                   con.publish('/turtlebot_servo', {'data':p3*256+p2});
            break;
          case 20: var p3=Math.round((Item.axes3+1)*90);
                   var p2=Math.round((Item.axes2+1)*90);
                   con.publish('/turtlebot_servo', {'data':p3*256+p2});
            break;
          default:
            break;
          }
    }
    // голос
    var cam_poz1=90;  // вверх-вниз
    var cam_poz2=90;  // влево-вправо
    var go_poz=new Array(0,0,0,0,0,0);  // движение робота для cmd_vel

    var fraza=new Object();
    fraza={
          cam_up1:"камера вверх",
          cam_bottom1:"камера вниз",
          cam_left1:"камера влево",
          cam_left2:"камера лего",
          cam_left3:"камера в лего",
          cam_right1:"камера вправо",
          cam_right2:"камера права",
          cam_right3:"камера право",
          robot_forward1:"роберт вперед",
          robot_forward2:"роберт перед",
          robot_back1:"роберт назад",
          robot_left1:"роберт влево",
          robot_right1:"роберт вправо",
          robot_right2:"роберт право",
          robot_right3:"роберт права",
          robot_stop1:"роберт стоять"
          };
       function get_speech_res(evt) {
           var str1=document.getElementById("res_speech").value;
           alert(str1);
           for(var k in fraza)
             {
             if(str1.search(fraza[k])!=-1)
                  {//alert(fraza[k]);
                   document.getElementById("speech1").value=k;
                   var kk=""+str1.replace(fraza[k],"");
                   if(kk.length<1) 
                      kk="10";
                   document.getElementById("speech2").value=kk;
                   document.getElementById('button2').click();         
                   break;}
             else ;
             }
    }




    // send голос
    function send_ros2() {
        var action1=document.getElementById("speech1").value;
        var value1=parseInt(document.getElementById("speech2").value);
        //**** движение камеры 
        //**** джойстик1 - вверх-вниз
        //**** джойстик2 - влево-вправо
        if(action1.search("cam_up")!=-1)
          {cam_poz1=Math.min(cam_poz1+value1,180);
          document.getElementById("cam_poz1").value=cam_poz1.toString();
          con.publish('/turtlebot_servo', {'data':parseInt(cam_poz1+256*cam_poz2)});
          }
        else if(action1.search("cam_down")!=-1)
          {cam_poz1=Math.max(cam_poz1-value1,0);
          document.getElementById("cam_poz1").value=cam_poz1.toString();
          con.publish('/turtlebot_servo', {'data':parseInt(cam_poz1+256*cam_poz2)});
          }
        else if(action1.search("cam_left")!=-1)
          {cam_poz2=Math.max(cam_poz2-value1,0);
          document.getElementById("cam_poz2").value=cam_poz2.toString();
          con.publish('/turtlebot_servo', {'data':parseInt(cam_poz1+256*cam_poz2)});
          }
        else if(action1.search("cam_right")!=-1)
          {cam_poz2=Math.min(cam_poz2+value1,180);
          document.getElementById("cam_poz2").value=cam_poz2.toString();
          con.publish('/turtlebot_servo', {'data':parseInt(cam_poz1+256*cam_poz2)});
          }
        //************* движение turtlebot
        else if(action1.search("robot_forward")!=-1)
          {go_poz[0]=1;go_poz[5]=0;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
          }
        else if(action1.search("robot_back")!=-1)
          {go_poz[0]=-1;go_poz[5]=0;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
          }
        else if(action1.search("robot_left")!=-1)
          {go_poz[5]=-1;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
          }
        else if(action1.search("robot_right")!=-1)
          {go_poz[5]=1;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
          }
        else if(action1.search("robot_stop")!=-1)
          {go_poz[0]=0;go_poz[5]=0;
          con.publish('/cmd_vel', {"linear":{"x":go_poz[0],"y":0,"z":0},"angular":{"x":0,"y":0,"z":go_poz[5]}});
          }
        else ;
    }

function new_robot(address)
  {
  alert(address);
  choice_robot=address;
  con = new Bridge("ws://"+address+":9090");
  }

function new_camera(topic)
  {
  document.getElementById("camera_robot").src="http://"+choice_robot+":8080/stream?topic="+topic;
  }
</script>

</head>
<body>
<h2 id="start">Удаленное управление Turtlebot - голос</h2>
<h3 id="">Настройки</h3>
    <form id=formoptions name=formoptions action="javascript:void();" onsubmit="feturn false;">
      Робот
      <select name=choice_robot id=choice_robot onchange='choice_robot=this.value;new_robot(this.value)'>
        <option value="192.168.1.103"> 192.168.1.103:9090 
      </select>
      
Камера
      <select name=choice_camera id=choice_camera onchange='new_camera(this.value)'>
        <option value="/usb_cam1/image_raw"> /usb_cam1/image_raw
        <option value="/camera/depth/image_raw"> /camera/depth/image_raw
         <option value="/camera/rgb/image_mono"> /camera/rgb/image_mono
        <option value="/camera/rgb/image_color" selected> /camera/rgb/image_color
      </select>
      
Служебные поля
      <input name=res id=res>
      <input name=speech1 id=speech1>
      <input name=speech2 id=speech2>
      <input name=cam_poz1 id=cam_poz1 value=90>
      <input name=cam_poz2 id=cam_poz2 value=90>
      
 battery
           <span id="battery"> - </span>
      
      <input id=res_speech type=text x-webkit-speech onwebkitspeechchange='get_speech_res(event);'>
    </form>
    <button id='button1' value='send' style='visibility:hidden'></button>
    <button id='button2' value='send' style='visibility:hidden'></button>


<script type="text/javascript">
gamepadSupport.init();
main();
</script>

<img id=camera_robot src="http://192.168.1.103:8080/stream?topic=/camera/rgb/image_color">

</body>
</html>

Скачать архив gamepad.html+ros.js+gamepad.js

Запуск

Копируем в vp_turtlebot1/www (там находятся файлы speech.html и ros.js) файлы gamepad.html и gamepad.js

И запуск — комп с Turtlebot — терминал Guake terminal
Терминал 0

roscore

Терминал 1

rosrun roswww webserver.py

Терминал 2

roslaunch vp_turtlebot1 vp_turtlebot_1_1.launch

Терминал 3

roslaunch turtlebot_bringup minimal.launch

Терминал 4

roslaunch turtlebot_bringup kinect.launch

Заходим в браузер с компа в сети или из внешней сети (открыть порты 8000,9090,8080)

Публикация в топики cmd_vel и turtlebot_servo при пользовании джойстиком

Скачать в репозиторий

Далее — удаленное управление в браузере с помощью kinect


Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение