文章目录


前言

  ROS Web tools社区开发了很多功能强大的web功能包。针对本篇文章,创建新的工作空间catkin_js_ws,并进行初始化等操作。

一、rosbridge_suite元功能包

  rosbridge_suite功能包用于完成web浏览器和ROS之间的数据交互,是一种中间件,屏蔽了ROS中复杂的算法、接口、消息传递机制等,使用socket序列化协议为机器人应用提供更为简单的接口。
  rosbridge_suite允许使用html5 web sockets或者标准的posix ip sockets进行ros的消息传送。
安装,命令如下:

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

该元功能包包含如下三个功能包:

  1. rosbridge_library:提供ROS消息与JSON消息之间转换的python API
  2. rosbridge_server:提供websocket服务
  3. rosapi:通过服务调用来获取ROS中的Topic和Parameters

二、roslibjs、ros2djs、ros3djs功能包

ROS web tools开发了一系列rosbridge的客户端功能包,可以通过web浏览器发送JSON命令,在不同场景中实现ROS丰富的功能。

  1. roslibjs:实现了ROS中的部分功能,例如Topic、Server、actionlib、TF、URDF等。
  2. ros2djs:在roslibjs的基础上提供二维可视化管理工具,例如在web浏览器中可视化显示二维地图。
  3. ros3djs:提供三维可视化工具,可以基于web创建一个rviz实例,三维显示URDF、TF等信息。

这三个功能包需要通过源码编译的方式进行安装,命令如下:

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

下载源码到catkin_ws工作空间,即可使用catkin_make命令进行编译。

三、tf2_web_republisher功能包

该功能包可以计算TF数据,并且发送到ros3djs客户端,实现机器人的运动。
需要通过源码编译的方式进行安装,命令如下:

sudo apt-get install ros-kinetic-tf2-ros
git clone https://github.com/RobotWebTools/tf2_web_republisher

工作空间src目录,如图所示:
在这里插入图片描述
然后执行编译命令,编译成功,如下:
请添加图片描述

四、创建web应用

功能描述:通过web远程控制机器人运动,并且显示机器人的三维模型。
实现原理:使用keyboardteleopjs功能包,通过JavaScript实现浏览器中对键盘按键的识别,并且发布Twist消息。Twist消息会由rosbridge的客户端使用JSON命令通过web sockets发送到服务器,然后服务器负责解析消息,通过controller控制机器人移动。而tf2_web_republisher会将机器人的TF数据通过rosbridge发送到客户端,在ros3djs的可视化显示中更新机器人状态。
创建功能包web_gui,创建keyboardteleop.html文件,代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-3.5.1.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-3.5.1.slim.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.12.4.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="http://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/blitzer/jquery-ui.css">
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/cupertino/jquery-ui.css">
    <script src="https://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script>
    <script src="https://static.robotwebtools.org/roslibjs/current/roslib.js"></script>
    <script src="/home/zt/catkin_js_ws/src/ros3djs/build/ros3d.js"></script>
    <script src="/home/zt/catkin_js_ws/src/ros3djs/build/ros3d.min.js"></script>
    <script src="/home/zt/catkin_js_ws/src/web_gui/build/keyboardteleop.js"></script>

<script>
  /**
   * Setup all GUI elements when the page is loaded. 
   */

  var teleop_topic = '/cmd_vel'
  var base_frame = 'odom';

  var init_flag = false

function submit_values(){
  teleop_topic = document.getElementById("tele_topic").value;
  base_frame = document.getElementById("base_frame_name").value;

  init_flag = true;
  init();
}

function init() {

	if(init_flag == true)
	{
		// Connecting to ROS.
		var ros = new ROSLIB.Ros({
			url : 'ws://localhost:9090'
		});


		// Initialize the teleop.
		var teleop = new KEYBOARDTELEOP.Teleop({
			ros : ros,
			topic : teleop_topic
		});

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

		});

		// Add a grid.
		viewer.addObject(new ROS3D.Grid());

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

		// Setup the URDF client.

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


	///////////////////////////////////////////////////////////////////////////////////////////////////

		// Create a UI slider using JQuery UI.
		$('#speed-slider').slider({
			range : 'min',
			min : 0,
			max : 100,
			value : 90,
			slide : function(event, ui) {
				// Change the speed label.
				$('#speed-label').html('Speed: ' + ui.value + '%');
				// Scale the speed.
				teleop.scale = (ui.value / 100.0);
			}
		});

		// Set the initial speed .
		$('#speed-label').html('Speed: ' + ($('#speed-slider').slider('value')) + '%');
		teleop.scale = ($('#speed-slider').slider('value') / 100.0);

		init_flag = false;
	}
}

</script>
</head>

<body onload="init()">
  <h1>Web-browser keyboard teleoperation</h1>

	<form >
		Teleop topic:<br>
		<input type="text" name="Teleop Topic" id='tele_topic' value="/cmd_vel">
		<br>
		Base frame:<br>
		<input type="text" name="Base frame" id='base_frame_name' value="/odom">
		<br>
	 <input type="button" onmousedown="submit_values()" value="Submit"> 
	</form> 

  <p>Run the following commands in the terminal then refresh this page. Check the JavaScript
    console for the output.</p>
  <ol>
    <li><tt>roslaunch mrobot_gazebo view_mrobot_with_kinect_gazebo.launch </tt></li>
    <li><tt>rosrun tf2_web_republisher tf2_web_republisher </tt></li>
    <li><tt>roslaunch rosbridge_server rosbridge_websocket.launch</tt></li>
    <li>Use WASD on your keyboard to move the robot (must have this browser window focused).</li>
  </ol>
  <div id="speed-label"></div>
  <div id="speed-slider"></div>
  <div id="urdf"></div>
</body>

</html>

关键代码解释如下:

var ros = new ROSLIB.Ros({
			url : 'ws://localhost:9090'
		});

创建一个ROSLIB.Ros对象用于连接rosbridge_server,如果rosbridge_server位于本机,IP使用localhost,否则需要修改为相应的IP地址。

var teleop = new KEYBOARDTELEOP.Teleop({
			ros : ros,
			topic : teleop_topic
		});

创建一个KEYBOARDTELEOP.Teleop对象,用来识别键盘按键并且发布消息,发布的话题通过变量teleop_topic设置,也就是”/cmd_vel“,设置了ROS的节点对象ros。

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

		});
viewer.addObject(new ROS3D.Grid());
创建一个ROS3D.Viewer的可视化对象,用于显示机器人的URDF模型,同时设置了可视化区域的分辨率尺寸,还通过addObject方法在可视化区域中添加了背景网格。
	var tfClient = new ROSLIB.TFClient({
			ros : ros,
			fixedFrame : base_frame,
			angularThres : 0.01,
			transThres : 0.01,
			rate : 10.0
		});

创建一个TF客户端,订阅tf2_web_republisher功能包发布的TF数据,更新可视化对象中的机器人状态。其中有一个似曾相识的参数——fixedFrame,与rviz中的属性相同。

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

创建一个URDF客户端,加载机器人模型,设置ROS节点、TF客户端模型加载路径,使用ROS3D.COLLADA_LOADER加载器,通过ROS中的robot_description参数将模型加载到COLLADA文件中。

		$('#speed-slider').slider({
			range : 'min',
			min : 0,
			max : 100,
			value : 90,
			slide : function(event, ui) {
				// Change the speed label.
				$('#speed-label').html('Speed: ' + ui.value + '%');
				// Scale the speed.
				teleop.scale = (ui.value / 100.0);
			}
		});

		// Set the initial speed .
		$('#speed-label').html('Speed: ' + ($('#speed-slider').slider('value')) + '%');
		teleop.scale = ($('#speed-slider').slider('value') / 100.0);

创建一个滑动条,控制机器人的速度大小。

	<form >
		Teleop topic:<br>
		<input type="text" name="Teleop Topic" id='tele_topic' value="/cmd_vel">
		<br>
		Base frame:<br>
		<input type="text" name="Base frame" id='base_frame_name' value="/odom">
		<br>
	 <input type="button" onmousedown="submit_values()" value="Submit"> 
	</form> 

创建两个输入框,用于设置速度控制的话题名和基坐标系名,创建确认按钮,点击后会提交输入框的表单,修改程序中的变量值。

五、使用web浏览器控制机器人

这里使用之前自定义的机器人模型,启动机器人模型,命令如下:

roslaunch robot_sim_gazebo robot.launch

启动成功,RVIZ效果如下:
在这里插入图片描述
gazebo效果如下:
在这里插入图片描述

仿真器启动成功后,就可以启动tf2_web_republisher和rosbridge_server了,命令如下:

rosrun tf2_web_republisher tf2_web_republisher
roslaunch rosbridge_server rosbridge_websocket.launch

现在,服务器的节点全部启动成功。以网页的形式打开keyboardteleop.html,效果如下:
请添加图片描述

  点击submit按钮后,下方会出现速度滑动条和三维可视化界面,机器人很快就在界面中加载出现,类似于RVIZ中的可视化区域。
  如果要使用键盘按键控制机器人的移动,请确保鼠标点在网页上。然后我们就可以使用键盘上的W、A、S、D键控制gazebo仿真器中的机器人前后左右移动,web浏览器中的机器人状态也会更新。
  在以后的学习中,还可以基于web功能包实现web浏览器中的SLAM、导航、语音控制等复杂功能。http://robotwebtools.org/这个网站上提供了很多库用来开发和ROS相关的web应用。