www: Added minicolors colorpicker for lights
[ros_wild_thumper.git] / www / index.html
1 <!doctype html>
2 <html>
3         <head>
4                 <meta charset="utf-8" />
5
6                 <link rel="stylesheet" href="assets/stylesheets/bootstrap.min.css">
7                 <link rel="stylesheet" href="assets/stylesheets/jquery-ui.css">
8                 <link rel="stylesheet" href="assets/stylesheets/jquery.minicolors.css">
9
10                 <style>
11                 .minicolors-theme-default.minicolors { margin: 5px; }
12                 </style>
13
14                 <script type="text/javascript">
15                 function init() {
16                         var ros = new ROSLIB.Ros();
17                         ros.connect('ws://wildthumper:9090');
18                         var isDragging = false;
19
20                         ros.on('connection', function() {
21                                 $("#information").append(`
22                                 <div class="alert alert-dismissible alert-success">
23                                         <span data-dismiss="alert">Connected to websocket server.</span>
24                                 </div>
25                                 `);
26                         });
27
28                         ros.on('error', function(error) {
29                                 $("#information").append(`
30                                 <div class="alert alert-dismissible alert-danger">
31                                         <span data-dismiss="alert">Error connecting to websocket server.</span>
32                                 </div>
33                                 `);
34                         });
35
36                         ros.on('close', function() {
37                                 $("#information").append(`
38                                 <div class="alert alert-dismissible alert-info">
39                                         <span data-dismiss="alert">Connection to websocket server closed.</span>
40                                 </div>
41                                 `);
42                         });
43
44                         //tfClient.subscribe('base_link', function(tf) {
45                         //      var now = new Date();
46                         //      $("#pose").text(now.toLocaleTimeString() + ": (" + tf.translation.x + ", " + tf.translation.y + ")");
47
48                         //      robotMarker.x = tf.translation.x;
49                         //      robotMarker.y = -tf.translation.y;
50                         //      robotMarker.rotation = viewer2D.scene.rosQuaternionToGlobalTheta(tf.rotation);
51                         //});
52                         var poseTopic = new ROSLIB.Topic({ros: ros, name: '/robot_pose', messageType: 'geometry_msgs/Pose'});
53                         var sensorTopic = new ROSLIB.Topic({ros: ros, name: '/sensors', messageType: 'wild_thumper/Sensor'});
54                         var batteryTopic = new ROSLIB.Topic({ros: ros, name: '/battery', messageType: 'sensor_msgs/BatteryState'});
55                         var ledStripeTopic = new ROSLIB.Topic({ros: ros, name: '/led_stripe', messageType: 'wild_thumper/LedStripe'});
56
57                         poseTopic.subscribe(function(message) {
58                                 var now = new Date();
59                                 $("#pose").text(now.toLocaleTimeString() + ": (" + message.position.x + ", " + message.position.y + ")");
60                         });
61
62                         sensorTopic.subscribe(function(message) {
63                                 sensordiv = $("#sensors")
64                                 sensordiv.find("input[name=light]").val(message.light);
65                                 sensordiv.find("input[name=temp]").val(message.temp.toFixed(1));
66                                 sensordiv.find("input[name=humidity]").val(message.humidity);
67                                 sensordiv.find("input[name=pressure]").val(message.pressure.toFixed(1));
68                                 sensordiv.find("input[name=co]").val(message.co);
69                         });
70
71                         batteryTopic.subscribe(function(message) {
72                                 powerdiv = $("#power");
73                                 powerdiv.find("input[name=voltage]").val(message.voltage.toFixed(1));
74                                 powerdiv.find("input[name=current]").val(message.current.toFixed(1));
75                         });
76
77                         viewer2D = new ROS2D.Viewer({
78                                 divID: 'map',
79                                 width: 640,
80                                 height: 480,
81                                 background: "#efefef"
82                         });
83                         $('#map')
84                         .bind('mousewheel', function(e) {
85                                 if (e.originalEvent.wheelDelta/120 > 0) {
86                                         viewer2D.scaleToDimensions(10, 10)
87                                 } else {
88                                         viewer2D.scaleToDimensions(5, 5)
89                                 }
90                         })
91                         .mousedown(function() {
92                                 isDragging = true;
93                                 mousePreX = undefined;
94                                 mousePreY = undefined;
95                         })
96                         .mouseup(function() {
97                                 isDragging = false;
98                         })
99                         .mousemove(function(event) {
100                                 if (isDragging) {
101                                         if (mousePreX != undefined && mousePreY != undefined) {
102                                                 var diffX = event.pageX - mousePreX;
103                                                 var diffY = event.pageY - mousePreY;
104                                                 console.log("Moving viewer2D by " + diffX + ", " + diffY);
105                                                 viewer2D.shift(diffX, diffY);
106                                         }
107                                         mousePreX = event.pageX;
108                                         mousePreY = event.pageY;
109                                 }
110                         });
111
112                         // Setup the nav client.
113                         NAV2D.OccupancyGridClientNav({
114                                 ros : ros,
115                                 rootObject : viewer2D.scene,
116                                 viewer : viewer2D,
117                                 serverName : '/move_base'
118                         });
119
120                         // Initialize the teleop.
121                         var teleop = new KEYBOARDTELEOP.Teleop({
122                                 ros : ros,
123                                 topic : '/cmd_vel'
124                         });
125
126                         // Create a UI slider using JQuery UI.
127                         $('#speed-slider').slider({
128                                 range : 'min',
129                                 min : 0,
130                                 max : 100,
131                                 value : 50,
132                                 slide : function(event, ui) {
133                                         // Change the speed label.
134                                         $('#speed-label').html('Speed: ' + ui.value + '%');
135                                         // Scale the speed.
136                                         teleop.scale = (ui.value / 100.0);
137                                 }
138                         });
139
140                         // Set the initial speed.
141                         $('#speed-label').html('Speed: ' + ($('#speed-slider').slider('value')) + '%');
142                         teleop.scale = ($('#speed-slider').slider('value') / 100.0);
143
144                         $('.led_color').minicolors({
145                                 control: 'wheel',
146                                 format: 'rgb',
147                                 defaultValue: '#000000',
148                                 change: function(value) {
149                                         var rgb = $(this).minicolors('rgbObject');
150                                         var num = $(this).prop("name");
151                                         var msg = new ROSLIB.Message({
152                                                 leds: [{
153                                                         num: parseInt(num),
154                                                         red: parseInt(rgb.r*127/255),
155                                                         green: parseInt(rgb.g*127/255),
156                                                         blue: parseInt(rgb.b*127/255)
157                                                 }]
158                                         });
159                                         ledStripeTopic.publish(msg);
160                                 }
161                         });
162                 }
163                 </script>
164                 <title>Wild Thumper control</title>
165         </head>
166         <body onload="init()">
167                 <div class="container-fluid">
168                         <div id="information">
169                         </div>
170
171                         <nav class="navbar navbar-expand-lg navbar-light bg-light">
172                                 <a class="navbar-brand" href="#">Wild Thumper</a>
173                                 <ul class="nav nav-tabs" role="tablist">
174                                         <li class="nav-item">
175                                                 <a class="nav-link active" href="#data" data-toggle="tab" role="tab">Data</a>
176                                         </li>
177                                         <li class="nav-item">
178                                                 <a class="nav-link" href="#navigation" data-toggle="tab" role="tab">Navigation</a>
179                                         </li>
180                                         <li class="nav-item">
181                                                 <a class="nav-link" href="#lights" data-toggle="tab" role="tab">Lights</a>
182                                         </li>
183                                 </ul>
184                         </nav>
185                         <div class="tab-content">
186                                 <div id="data" class="tab-pane active" role="tabpanel">
187                                         <div class="row">
188                                                 <div id="power" class="col-auto">
189                                                         <h4>Power</h4>
190                                                         <label>Voltage:</label>
191                                                         <div class="input-group">
192                                                                 <input type=text name="voltage" class="form-control" readonly>
193                                                                 <div class="input-group-append">
194                                                                         <span class="input-group-text">V</span>
195                                                                 </div>
196                                                         </div>
197                                                         <label>Current:</label>
198                                                         <div class="input-group">
199                                                                 <input type=text name="current" class="form-control" readonly>
200                                                                 <div class="input-group-append">
201                                                                         <span class="input-group-text">A</span>
202                                                                 </div>
203                                                         </div>
204                                                 </div>
205                                                 <div id="sensors" class="col-auto">
206                                                         <h4>Sensors</h4>
207                                                         <label>Light:</label>
208                                                         <div class="input-group">
209                                                                 <input type=text name="light" class="form-control" readonly>
210                                                                 <div class="input-group-append">
211                                                                         <span class="input-group-text">lx</span>
212                                                                 </div>
213                                                         </div>
214                                                         <label>Temperature:</label>
215                                                         <div class="input-group">
216                                                                 <input type=text name="temp" class="form-control" readonly>
217                                                                 <div class="input-group-append">
218                                                                         <span class="input-group-text">&#x2103</span>
219                                                                 </div>
220                                                         </div>
221                                                         <label>Humidity:</label>
222                                                         <div class="input-group">
223                                                                 <input type=text name="humidity" class="form-control" readonly>
224                                                                 <div class="input-group-append">
225                                                                         <span class="input-group-text">%</span>
226                                                                 </div>
227                                                         </div>
228                                                         <label>Pressure:</label>
229                                                         <div class="input-group">
230                                                                 <input type=text name="pressure" class="form-control" readonly>
231                                                                 <div class="input-group-append">
232                                                                         <span class="input-group-text">kPa</span>
233                                                                 </div>
234                                                         </div>
235                                                         <label>CO:</label>
236                                                         <input type=text name="co" class="form-control" readonly>
237                                                 </div>
238                                         </div>
239                                 </div>
240                                 <div id="navigation" class="tab-pane" role="tabpanel">
241                                         <div id="pose"></div>
242                                         <div id="map"></div>
243                                         <div id="speed-label"></div>
244                                         <div id="speed-slider"></div>
245                                 </div>
246                                 <div id="lights" class="tab-pane" role="tabpanel">
247                                         <div class="row d-flex align-items-center">
248                                                 <div class="col-md-1">
249                                                         <div class="float-right align-middle">
250                                                                 <input class="led_color" type="hidden" name="15"/>
251                                                                 <input class="led_color" type="hidden" name="14"/>
252                                                         </div>
253                                                 </div>
254                                                 <div class="col-md-2" >
255                                                         <div class="d-flex justify-content-center">
256                                                                 <input class="led_color" type="hidden" name="0"/>
257                                                                 <input class="led_color" type="hidden" name="1"/>
258                                                                 <input class="led_color" type="hidden" name="2"/>
259                                                                 <input class="led_color" type="hidden" name="3"/>
260                                                         </div>
261                                                         <div>
262                                                                 <div style="background: url('assets/images/wt_top.png'); background-size: cover; background-size: 100%; background-repeat: no-repeat; height: 260px;">
263                                                                         <div class="d-flex justify-content-center" style="padding-top: 70px;">
264                                                                                 <input class="led_color" type="hidden" name="7"/>
265                                                                                 <input class="led_color" type="hidden" name="6"/>
266                                                                                 <input class="led_color" type="hidden" name="5"/>
267                                                                                 <input class="led_color" type="hidden" name="4"/>
268                                                                         </div>
269                                                                 </div>
270                                                         </div>
271                                                         <div class="d-flex justify-content-center">
272                                                                 <input class="led_color" type="hidden" name="8"/>
273                                                                 <input class="led_color" type="hidden" name="9"/>
274                                                                 <input class="led_color" type="hidden" name="10"/>
275                                                                 <input class="led_color" type="hidden" name="11"/>
276                                                         </div>
277                                                 </div>
278                                                 <div class="col-md-1">
279                                                         <div class="float-left align-middle">
280                                                                 <input class="led_color" type="hidden" name="13"/>
281                                                                 <input class="led_color" type="hidden" name="12"/>
282                                                         </div>
283                                                 </div>
284                                         </div>
285                                 </div>
286                         </div>
287                 </div>
288                 <script src="assets/javascripts/jquery-3.3.1.min.js"></script>
289                 <script src="assets/javascripts/popper.min.js"></script>
290                 <script src="assets/javascripts/bootstrap.min.js"></script>
291                 <script src="assets/javascripts/jquery-ui.min.js"></script>
292                 <script src="assets/javascripts/easeljs.min.js"></script>
293                 <script src="assets/javascripts/eventemitter2.js"></script>
294                 <script src="assets/javascripts/roslib.js"></script>
295                 <script src="assets/javascripts/ros2d.js"></script>
296                 <script src="assets/javascripts/nav2d.js"></script>
297                 <script src="assets/javascripts/keyboardteleop.js"></script>
298                 <script src="assets/javascripts/jquery.minicolors.js"></script>
299         </body>
300 </html>