Added initial rosweb file
[ros_wild_thumper.git] / www / index.html
1 <!doctype html>
2 <!--
3         Server: python -m SimpleHTTPServer
4         Bridge: roslaunch rosbridge_server rosbridge_websocket.launch
5 -->
6 <html>
7         <head>
8                 <meta charset="utf-8" />
9
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" />
12
13                 <script type="text/javascript">
14                 function init() {
15                         var ros = new ROSLIB.Ros();
16                         ros.connect('ws://wildthumper:9090');
17                         var isDragging = false;
18
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>
23                                 </div>
24                                 `);
25                         });
26
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>
31                                 </div>
32                                 `);
33                         });
34
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>
39                                 </div>
40                                 `);
41                         });
42
43                         //tfClient.subscribe('base_link', function(tf) {
44                         //      var now = new Date();
45                         //      $("#pose").text(now.toLocaleTimeString() + ": (" + tf.translation.x + ", " + tf.translation.y + ")");
46
47                         //      robotMarker.x = tf.translation.x;
48                         //      robotMarker.y = -tf.translation.y;
49                         //      robotMarker.rotation = viewer2D.scene.rosQuaternionToGlobalTheta(tf.rotation);
50                         //});
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'});
54
55                         poseTopic.subscribe(function(message) {
56                                 var now = new Date();
57                                 $("#pose").text(now.toLocaleTimeString() + ": (" + message.position.x + ", " + message.position.y + ")");
58                         });
59
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);
67                         });
68
69                         itest = 123.4556;
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));
74                         });
75
76                         viewer2D = new ROS2D.Viewer({
77                                 divID: 'map',
78                                 width: 640,
79                                 height: 480,
80                                 background: "#efefef"
81                         });
82                         $('#map')
83                         .bind('mousewheel', function(e) {
84                                 if (e.originalEvent.wheelDelta/120 > 0) {
85                                         viewer2D.scaleToDimensions(10, 10)
86                                 } else {
87                                         viewer2D.scaleToDimensions(5, 5)
88                                 }
89                         })
90                         .mousedown(function() {
91                                 isDragging = true;
92                                 mousePreX = undefined;
93                                 mousePreY = undefined;
94                         })
95                         .mouseup(function() {
96                                 isDragging = false;
97                         })
98                         .mousemove(function(event) {
99                                 if (isDragging) {
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);
105                                         }
106                                         mousePreX = event.pageX;
107                                         mousePreY = event.pageY;
108                                 }
109                         });
110
111                         // Setup the nav client.
112                         NAV2D.OccupancyGridClientNav({
113                                 ros : ros,
114                                 rootObject : viewer2D.scene,
115                                 viewer : viewer2D,
116                                 serverName : '/move_base'
117                         });
118
119                         // Initialize the teleop.
120                         var teleop = new KEYBOARDTELEOP.Teleop({
121                                 ros : ros,
122                                 topic : '/cmd_vel'
123                         });
124
125                         // Create a UI slider using JQuery UI.
126                         $('#speed-slider').slider({
127                                 range : 'min',
128                                 min : 0,
129                                 max : 100,
130                                 value : 50,
131                                 slide : function(event, ui) {
132                                         // Change the speed label.
133                                         $('#speed-label').html('Speed: ' + ui.value + '%');
134                                         // Scale the speed.
135                                         teleop.scale = (ui.value / 100.0);
136                                 }
137                         });
138
139                         // Set the initial speed.
140                         $('#speed-label').html('Speed: ' + ($('#speed-slider').slider('value')) + '%');
141                         teleop.scale = ($('#speed-slider').slider('value') / 100.0);
142                 }
143                 </script>
144         </head>
145         <body onload="init()">
146                 <div class="container-fluid">
147                         <div id="information">
148                         </div>
149
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>
155                                         </li>
156                                         <li class="nav-item">
157                                                 <a class="nav-link" href="#navigation" data-toggle="tab" role="tab">Navigation</a>
158                                         </li>
159                                 </ul>
160                         </nav>
161                         <div class="tab-content">
162                                 <div id="data" class="tab-pane active" role="tabpanel">
163                                         <div class="row">
164                                                 <div id="power" class="col-auto">
165                                                         <h4>Power</h4>
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>
170                                                         </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>
175                                                         </div>
176                                                 </div>
177                                                 <div id="sensors" class="col-auto">
178                                                         <h4>Sensors</h4>
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>
183                                                         </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">&#x2103</div>
188                                                         </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>
193                                                         </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>
198                                                         </div>
199                                                         <label>CO:</label>
200                                                         <input type=text name="co" class="form-control" readonly>
201                                                 </div>
202                                         </div>
203                                 </div>
204                                 <div id="navigation" class="tab-pane" role="tabpanel">
205                                         <div id="pose"></div>
206                                         <div id="map"></div>
207                                         <div id="speed-label"></div>
208                                         <div id="speed-slider"></div>
209                                 </div>
210                         </div>
211                 </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>
222         </body>
223 </html>