Продолжение. Начало — Часть 1 и Часть 2.
В этой части рассмотрим голосовое управление Turtlebot через браузер.
Запуск Turtlebot-а
Запуск Turtlebot
Для запуска Turtlebot (можно посмотреть здесь или здесь)
Запуск Turtlebot
roslaunch turtlebot_bringup minimal.launch
Запуск kinect
roslaunch turtlebot_bringup kinect.launch
У меня kinect горит зеленый светодиод — сразу не запускается
Запускаю предварительно
freenect glview
(установка пакета — sudo apt-get install libfreenect-demos)
Затем выхожу и заново
roslaunch turtlebot_bringup kinect.launch
Теперь определимся с данными, которые хотим отправлять Turtlebot-у и получать от него.
Список тем ROS для отправки-получения сообщений
Для удаленного управления нас интересуют следующее:
— показания заряда батареи — получение данных
topic — /turtlebot_node/sensor_state —
— получение потока данных с kinect
topic:
/camera/rgb/image_color
/camera/rgb/image_mono
/camera/depth/image
— получение потока данных с usb-камеры
/usb_cam1/image_raw
— управление usb-камерой
отправка сообщений в топик /turtlebot_servo
— управление движением turtlebot
отправка сообщений в топик /cmd_vel
Написание html-файла
Пишем html файл — speech.html, использующий библиотеку ros.js
Для распознавания речи используется GoogleSpeech API — поддерживается в html5 вставкой в форму поля input c с атрибутом x-webkit-speech
Вот содержимое файла speech.html
<html>
<head>
<script src='ros.js'></script>
<script type="text/javascript">
var choice_robot="192.168.1.103";
var con = new Bridge("ws://192.168.1.103:9090");
var get_data2=function(msg)
{
document.getElementById("battery").innerHTML=parseInt(msg/65535*100)+" %";
var voltage=parseInt(msg/65535*100);
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_ros2(); }, true);
}
// голос
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;
for(var k in fraza)
{
if(str1.search(fraza[k])!=-1)
{
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);
//**** движение камеры
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.0,"z": 0.0},"angular":{"x": 0.0,"y": 0.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.0,"z": 0.0},"angular":{"x": 0.0,"y": 0.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.0,"z": 0.0},"angular":{"x": 0.0,"y": 0.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.0,"z": 0.0},"angular":{"x": 0.0,"y": 0.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='button2' value='send' style='visibility:hidden'></button>
<script type="text/javascript">
main();
</script>
<img id=camera_robot src="http://192.168.1.103:8080/stream?topic=/camera/rgb/image_color">
</body>
</html>
Запуск
Создаем новый проект vp_turtlebot1
roscreate-pkg vp_turtlebot1 rosdep install vp_turtlebot1 rosmake vp_turtlebot1
В нем создаем командный файл vp_turtlebot1_1.launch следующего содержания
<launch>
<node name="rosbridge_server" pkg="rosbridge_server" type="rosbridge.py" >
<param name="io_method" value="mmap"></param>
</node>
<node name="mjpeg_server" pkg="mjpeg_server" type="mjpeg_server" >
</node>
<node name="serial_node" pkg="rosserial_python" type="serial_node.py" >
<param name="port" value="/dev/ttyACM0"></param>
</node>
<node name="usb_cam1" pkg="usb_cam" type="usb_cam_node" output="screen" >
<param name="video_device" value="/dev/video1"></param>
<param name="image_width" value="320"></param>
<param name="image_height" value="240"></param>
<param name="pixel_format" value="yuyv"></param>
<param name="camera_frame_id" value="usb_cam"></param>
<param name="io_method" value="mmap"></param>
</node>
<node name="image_view" pkg="image_view" type="image_view" respawn="false" output="screen">
<remap from="image" to="/usb_cam1/image_raw"/>
<param name="autosize" value="true"></param>
</node>
</launch>
Далее
roscd vp_turtlebot1 mkdir www
Копируем в www файлы speech.html и ros.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)


Далее — удаленное управление Turtlebot с помощью джойстика
