3 Server: python -m SimpleHTTPServer
4 Bridge: roslaunch rosbridge_server rosbridge_websocket.launch
8 <meta charset="utf-8" />
10 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
11 <link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
13 <script type="text/javascript">
15 var ros = new ROSLIB.Ros();
16 ros.connect('ws://wildthumper:9090');
17 var isDragging = false;
19 ros.on('connection', function() {
20 $("#information").append(`
21 <div class="alert alert-dismissible alert-success">
22 <span data-dismiss="alert">Connected to websocket server.</span>
27 ros.on('error', function(error) {
28 $("#information").append(`
29 <div class="alert alert-dismissible alert-danger">
30 <span data-dismiss="alert">Error connecting to websocket server.</span>
35 ros.on('close', function() {
36 $("#information").append(`
37 <div class="alert alert-dismissible alert-info">
38 <span data-dismiss="alert">Connection to websocket server closed.</span>
43 //tfClient.subscribe('base_link', function(tf) {
44 // var now = new Date();
45 // $("#pose").text(now.toLocaleTimeString() + ": (" + tf.translation.x + ", " + tf.translation.y + ")");
47 // robotMarker.x = tf.translation.x;
48 // robotMarker.y = -tf.translation.y;
49 // robotMarker.rotation = viewer2D.scene.rosQuaternionToGlobalTheta(tf.rotation);
51 var poseTopic = new ROSLIB.Topic({ros: ros, name: '/robot_pose', messageType : 'geometry_msgs/Pose'});
52 var sensorTopic = new ROSLIB.Topic({ros: ros, name: '/sensors', messageType : 'wild_thumper/Sensor'});
53 var batteryTopic = new ROSLIB.Topic({ros: ros, name: '/battery', messageType : 'sensor_msgs/BatteryState'});
55 poseTopic.subscribe(function(message) {
57 $("#pose").text(now.toLocaleTimeString() + ": (" + message.position.x + ", " + message.position.y + ")");
60 sensorTopic.subscribe(function(message) {
61 sensordiv = $("#sensors")
62 sensordiv.find("input[name=light]").val(message.light);
63 sensordiv.find("input[name=temp]").val(message.temp.toFixed(1));
64 sensordiv.find("input[name=humidity]").val(message.humidity);
65 sensordiv.find("input[name=pressure]").val(message.pressure.toFixed(1));
66 sensordiv.find("input[name=co]").val(message.co);
70 batteryTopic.subscribe(function(message) {
71 powerdiv = $("#power");
72 powerdiv.find("input[name=voltage]").val(message.voltage.toFixed(1));
73 powerdiv.find("input[name=current]").val(message.current.toFixed(1));
76 viewer2D = new ROS2D.Viewer({
83 .bind('mousewheel', function(e) {
84 if (e.originalEvent.wheelDelta/120 > 0) {
85 viewer2D.scaleToDimensions(10, 10)
87 viewer2D.scaleToDimensions(5, 5)
90 .mousedown(function() {
92 mousePreX = undefined;
93 mousePreY = undefined;
98 .mousemove(function(event) {
100 if (mousePreX != undefined && mousePreY != undefined) {
101 var diffX = event.pageX - mousePreX;
102 var diffY = event.pageY - mousePreY;
103 console.log("Moving viewer2D by " + diffX + ", " + diffY);
104 viewer2D.shift(diffX, diffY);
106 mousePreX = event.pageX;
107 mousePreY = event.pageY;
111 // Setup the nav client.
112 NAV2D.OccupancyGridClientNav({
114 rootObject : viewer2D.scene,
116 serverName : '/move_base'
119 // Initialize the teleop.
120 var teleop = new KEYBOARDTELEOP.Teleop({
125 // Create a UI slider using JQuery UI.
126 $('#speed-slider').slider({
131 slide : function(event, ui) {
132 // Change the speed label.
133 $('#speed-label').html('Speed: ' + ui.value + '%');
135 teleop.scale = (ui.value / 100.0);
139 // Set the initial speed.
140 $('#speed-label').html('Speed: ' + ($('#speed-slider').slider('value')) + '%');
141 teleop.scale = ($('#speed-slider').slider('value') / 100.0);
145 <body onload="init()">
146 <div class="container-fluid">
147 <div id="information">
150 <nav class="navbar navbar-expand-lg navbar-light bg-light">
151 <a class="navbar-brand" href="#">Wild Thumper</a>
152 <ul class="nav nav-tabs" role="tablist">
153 <li class="nav-item">
154 <a class="nav-link active" href="#data" data-toggle="tab" role="tab">Data</a>
156 <li class="nav-item">
157 <a class="nav-link" href="#navigation" data-toggle="tab" role="tab">Navigation</a>
161 <div class="tab-content">
162 <div id="data" class="tab-pane active" role="tabpanel">
164 <div id="power" class="col-auto">
166 <label>Voltage:</label>
167 <div class="input-group">
168 <input type=text name="voltage" class="form-control" readonly>
169 <div class="input-group-addon">V</div>
171 <label>Current:</label>
172 <div class="input-group">
173 <input type=text name="current" class="form-control" readonly>
174 <div class="input-group-addon">A</div>
177 <div id="sensors" class="col-auto">
179 <label>Light:</label>
180 <div class="input-group">
181 <input type=text name="light" class="form-control" readonly>
182 <div class="input-group-addon">lx</div>
184 <label>Temperature:</label>
185 <div class="input-group">
186 <input type=text name="temp" class="form-control" readonly>
187 <div class="input-group-addon">℃</div>
189 <label>Humidity:</label>
190 <div class="input-group">
191 <input type=text name="humidity" class="form-control" readonly>
192 <div class="input-group-addon">%</div>
194 <label>Pressure:</label>
195 <div class="input-group">
196 <input type=text name="pressure" class="form-control" readonly>
197 <div class="input-group-addon">kPa</div>
200 <input type=text name="co" class="form-control" readonly>
204 <div id="navigation" class="tab-pane" role="tabpanel">
205 <div id="pose"></div>
207 <div id="speed-label"></div>
208 <div id="speed-slider"></div>
212 <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
213 <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
214 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
215 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
216 <script src="http://static.robotwebtools.org/EaselJS/current/easeljs.min.js"></script>
217 <script src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.js"></script>
218 <script src="http://static.robotwebtools.org/roslibjs/current/roslib.js"></script>
219 <script src="http://static.robotwebtools.org/ros2djs/current/ros2d.js"></script>
220 <script src="http://static.robotwebtools.org/nav2djs/current/nav2d.js"></script>
221 <script src="http://static.robotwebtools.org/keyboardteleopjs/current/keyboardteleop.js"></script>