www: use vue.js-components to avoid duplicates
[ros_wild_thumper.git] / www / index.html
index 8a14cec..97428fe 100644 (file)
                <link rel="stylesheet" href="assets/stylesheets/bootstrap.min.css">
                <link rel="stylesheet" href="assets/stylesheets/jquery-ui.css">
                <link rel="stylesheet" href="assets/stylesheets/jquery.minicolors.css">
+               <link rel="stylesheet" href="assets/stylesheets/application.css">
 
-               <style>
-               .minicolors-theme-default.minicolors { margin: 5px; }
-               .bottom-leds > .minicolors-theme-default.minicolors { margin: 5px 0; }
-               .top-leds > .minicolors-theme-default.minicolors { margin-top: 70px; }
-               .wt-icon {background: url('assets/images/wt_top.png'); background-size: cover; background-size: 100%; background-repeat: no-repeat; background-position: center; height: 260px;}
-               </style>
-
-               <script type="text/javascript">
-               function init() {
-                       var ros = new ROSLIB.Ros();
-                       ros.connect('ws://wildthumper:9090');
-                       var isDragging = false;
-
-                       ros.on('connection', function() {
-                               $("#information").append(`
-                               <div class="alert alert-dismissible alert-success">
-                                       <span data-dismiss="alert">Connected to websocket server.</span>
-                               </div>
-                               `);
-                       });
-
-                       ros.on('error', function(error) {
-                               $("#information").append(`
-                               <div class="alert alert-dismissible alert-danger">
-                                       <span data-dismiss="alert">Error connecting to websocket server.</span>
-                               </div>
-                               `);
-                       });
-
-                       ros.on('close', function() {
-                               $("#information").append(`
-                               <div class="alert alert-dismissible alert-info">
-                                       <span data-dismiss="alert">Connection to websocket server closed.</span>
-                               </div>
-                               `);
-                       });
-
-                       //tfClient.subscribe('base_link', function(tf) {
-                       //      var now = new Date();
-                       //      $("#pose").text(now.toLocaleTimeString() + ": (" + tf.translation.x + ", " + tf.translation.y + ")");
-
-                       //      robotMarker.x = tf.translation.x;
-                       //      robotMarker.y = -tf.translation.y;
-                       //      robotMarker.rotation = viewer2D.scene.rosQuaternionToGlobalTheta(tf.rotation);
-                       //});
-                       var poseTopic = new ROSLIB.Topic({ros: ros, name: '/robot_pose', messageType: 'geometry_msgs/Pose'});
-                       var sensorTopic = new ROSLIB.Topic({ros: ros, name: '/sensors', messageType: 'wild_thumper/Sensor'});
-                       var batteryTopic = new ROSLIB.Topic({ros: ros, name: '/battery', messageType: 'sensor_msgs/BatteryState'});
-                       var ledStripeTopic = new ROSLIB.Topic({ros: ros, name: '/led_stripe', messageType: 'wild_thumper/LedStripe'});
-
-                       poseTopic.subscribe(function(message) {
-                               var now = new Date();
-                               $("#pose").text(now.toLocaleTimeString() + ": (" + message.position.x + ", " + message.position.y + ")");
-                       });
-
-                       sensorTopic.subscribe(function(message) {
-                               sensordiv = $("#sensors")
-                               sensordiv.find("input[name=light]").val(message.light);
-                               sensordiv.find("input[name=temp]").val(message.temp.toFixed(1));
-                               sensordiv.find("input[name=humidity]").val(message.humidity);
-                               sensordiv.find("input[name=pressure]").val(message.pressure.toFixed(1));
-                               sensordiv.find("input[name=co]").val(message.co);
-                       });
-
-                       batteryTopic.subscribe(function(message) {
-                               powerdiv = $("#power");
-                               powerdiv.find("input[name=voltage]").val(message.voltage.toFixed(1));
-                               powerdiv.find("input[name=current]").val(message.current.toFixed(1));
-                       });
-
-                       viewer2D = new ROS2D.Viewer({
-                               divID: 'map',
-                               width: 640,
-                               height: 480,
-                               background: "#efefef"
-                       });
-                       $('#map')
-                       .bind('mousewheel', function(e) {
-                               if (e.originalEvent.wheelDelta/120 > 0) {
-                                       viewer2D.scaleToDimensions(10, 10)
-                               } else {
-                                       viewer2D.scaleToDimensions(5, 5)
-                               }
-                       })
-                       .mousedown(function() {
-                               isDragging = true;
-                               mousePreX = undefined;
-                               mousePreY = undefined;
-                       })
-                       .mouseup(function() {
-                               isDragging = false;
-                       })
-                       .mousemove(function(event) {
-                               if (isDragging) {
-                                       if (mousePreX != undefined && mousePreY != undefined) {
-                                               var diffX = event.pageX - mousePreX;
-                                               var diffY = event.pageY - mousePreY;
-                                               console.log("Moving viewer2D by " + diffX + ", " + diffY);
-                                               viewer2D.shift(diffX, diffY);
-                                       }
-                                       mousePreX = event.pageX;
-                                       mousePreY = event.pageY;
-                               }
-                       });
-
-                       // Setup the nav client.
-                       NAV2D.OccupancyGridClientNav({
-                               ros : ros,
-                               rootObject : viewer2D.scene,
-                               viewer : viewer2D,
-                               serverName : '/move_base'
-                       });
-
-                       // Initialize the teleop.
-                       teleop = new KEYBOARDTELEOP.Teleop({
-                               ros : ros,
-                               topic : '/cmd_vel'
-                       });
-
-                       // Create a UI slider using JQuery UI.
-                       $('#speed-slider').slider({
-                               range : 'min',
-                               min : 0.10,
-                               max : 1.0,
-                               step : 0.05,
-                               value : 0.5,
-                               slide : function(event, ui) {
-                                       // Change the speed label.
-                                       $('#speed-label').html('Speed: ' + ui.value + ' m/s');
-                                       // Scale the speed.
-                                       teleop.scale = (ui.value * 2);
-                               }
-                       });
-
-                       // Set the initial speed.
-                       $('#speed-label').html('Speed: ' + ($('#speed-slider').slider('value')) + ' m/s');
-                       teleop.scale = ($('#speed-slider').slider('value') * 2);
+               <script src="assets/javascripts/jquery-3.3.1.min.js"></script>
+               <script src="assets/javascripts/popper.min.js"></script>
+               <script src="assets/javascripts/bootstrap.min.js"></script>
+               <script src="assets/javascripts/jquery-ui.min.js"></script>
+               <script src="assets/javascripts/easeljs.min.js"></script>
+               <script src="assets/javascripts/eventemitter2.js"></script>
+               <script src="assets/javascripts/roslib.js"></script>
+               <script src="assets/javascripts/ros2d.js"></script>
+               <script src="assets/javascripts/nav2d.js"></script>
+               <script src="assets/javascripts/keyboardteleop.js"></script>
+               <script src="assets/javascripts/jquery.minicolors.js"></script>
+               <script src="assets/javascripts/vue.js"></script>
+               <script src="assets/javascripts/application.js"></script>
 
-                       $('.led_color').minicolors({
-                               control: 'wheel',
-                               format: 'rgb',
-                               defaultValue: '#000000',
-                               change: function(value) {
-                                       var rgb = $(this).minicolors('rgbObject');
-                                       var nums = jQuery.parseJSON($(this).prop("name"));
-                                       var msg = new ROSLIB.Message({
-                                               leds: []
-                                       });
-                                       jQuery.each(nums, function(i, num) {
-                                               msg["leds"].push({
-                                                       num: num,
-                                                       red: parseInt(rgb.r*127/255),
-                                                       green: parseInt(rgb.g*127/255),
-                                                       blue: parseInt(rgb.b*127/255)
-                                               })
-                                       });
-                                       ledStripeTopic.publish(msg);
-                               }
-                       });
-               }
-               </script>
                <title>Wild Thumper control</title>
        </head>
        <body onload="init()">
                <div class="container-fluid">
                        <div id="information">
+                               <div v-for="(alert, id) in alerts" class="alert alert-dismissible}" v-bind:class="classObject(id)">
+                                       <span data-dismiss="alert">{{alert.message}}</span>
+                               </div>
                        </div>
 
                        <nav class="navbar navbar-expand-lg navbar-light bg-light">
                                <a class="navbar-brand" href="#">Wild Thumper</a>
                                <ul class="nav nav-tabs" role="tablist">
                                        <li class="nav-item">
-                                               <a class="nav-link active" href="#data" data-toggle="tab" role="tab">Data</a>
+                                               <a class="nav-link" href="#data" data-toggle="tab" role="tab">Data</a>
                                        </li>
                                        <li class="nav-item">
                                                <a class="nav-link" href="#navigation" data-toggle="tab" role="tab">Navigation</a>
                                        </li>
                                        <li class="nav-item">
-                                               <a class="nav-link" href="#lights" data-toggle="tab" role="tab">Lights</a>
+                                               <a class="nav-link active" href="#lights" data-toggle="tab" role="tab">Lights</a>
+                                       </li>
+                                       <li class="nav-item">
+                                               <a class="nav-link" href="#drive" data-toggle="tab" role="tab">Drive</a>
                                        </li>
                                </ul>
                        </nav>
+
                        <div class="tab-content">
-                               <div id="data" class="tab-pane active" role="tabpanel">
+                               <div id="data" class="tab-pane" role="tabpanel">
                                        <div class="row">
                                                <div id="power" class="col-auto">
                                                        <h4>Power</h4>
-                                                       <label>Voltage:</label>
-                                                       <div class="input-group">
-                                                               <input type=text name="voltage" class="form-control" readonly>
-                                                               <div class="input-group-append">
-                                                                       <span class="input-group-text">V</span>
-                                                               </div>
-                                                       </div>
-                                                       <label>Current:</label>
-                                                       <div class="input-group">
-                                                               <input type=text name="current" class="form-control" readonly>
-                                                               <div class="input-group-append">
-                                                                       <span class="input-group-text">A</span>
-                                                               </div>
-                                                       </div>
+                                                       <input-value v-model="voltage" label="Voltage" unit="V"></input-value>
+                                                       <input-value v-model="current" label="Current" unit="A"></input-value>
                                                </div>
                                                <div id="sensors" class="col-auto">
                                                        <h4>Sensors</h4>
-                                                       <label>Light:</label>
-                                                       <div class="input-group">
-                                                               <input type=text name="light" class="form-control" readonly>
-                                                               <div class="input-group-append">
-                                                                       <span class="input-group-text">lx</span>
-                                                               </div>
-                                                       </div>
-                                                       <label>Temperature:</label>
-                                                       <div class="input-group">
-                                                               <input type=text name="temp" class="form-control" readonly>
-                                                               <div class="input-group-append">
-                                                                       <span class="input-group-text">&#x2103</span>
-                                                               </div>
-                                                       </div>
-                                                       <label>Humidity:</label>
-                                                       <div class="input-group">
-                                                               <input type=text name="humidity" class="form-control" readonly>
-                                                               <div class="input-group-append">
-                                                                       <span class="input-group-text">%</span>
-                                                               </div>
-                                                       </div>
-                                                       <label>Pressure:</label>
-                                                       <div class="input-group">
-                                                               <input type=text name="pressure" class="form-control" readonly>
-                                                               <div class="input-group-append">
-                                                                       <span class="input-group-text">kPa</span>
-                                                               </div>
-                                                       </div>
-                                                       <label>CO:</label>
-                                                       <input type=text name="co" class="form-control" readonly>
+                                                       <input-value v-model="light" label="Light" unit="lx"></input-value>
+                                                       <input-value v-model="temp" label="Temperature" unit="&#x2103"></input-value>
+                                                       <input-value v-model="humidity" label="Humidity" unit="%"></input-value>
+                                                       <input-value v-model="pressure" label="Pressure" unit="kPa"></input-value>
+                                                       <input-value v-model="co" label="CO"></input-value>
                                                </div>
                                        </div>
                                </div>
                                <div id="navigation" class="tab-pane" role="tabpanel">
                                        <div id="pose"></div>
                                        <div id="map"></div>
-                                       <div id="speed-label"></div>
+                                       <div id="speed-label">Speed: {{speed}} m/s</div>
                                        <div id="speed-slider"></div>
                                </div>
-                               <div id="lights" class="tab-pane" role="tabpanel">
+                               <div id="lights" class="tab-pane active" role="tabpanel">
                                        <div class="row">
                                                <div class="col-md-2 offset-md-1" >
                                                        <div class="d-flex justify-content-center">
-                                                               <input class="led_color" type="hidden" name="[0]"/>
-                                                               <input class="led_color" type="hidden" name="[1]"/>
-                                                               <input class="led_color" type="hidden" name="[2]"/>
-                                                               <input class="led_color" type="hidden" name="[3]"/>
+                                                               <input class="led_color" type="hidden" :name="led" readonly="true" v-for="led in front_row" />
                                                        </div>
                                                        <div>
                                                                <div class="row wt-icon">
                                                                        <div class="col-md-2 align-self-center bottom-leds">
-                                                                               <input class="led_color" type="hidden" name="[14]"/>
-                                                                               <input class="led_color" type="hidden" name="[15]"/>
+                                                                               <input class="led_color" type="hidden" :name="led" readonly="true" v-for="led in bottom_left_row" />
                                                                        </div>
                                                                        <div class="col-md-8">
                                                                                <div class="d-flex justify-content-center top-leds">
-                                                                                       <input class="led_color" type="hidden" name="[7]"/>
-                                                                                       <input class="led_color" type="hidden" name="[6]"/>
-                                                                                       <input class="led_color" type="hidden" name="[5]"/>
-                                                                                       <input class="led_color" type="hidden" name="[4]"/>
+                                                                                       <input class="led_color" type="hidden" :name="led" readonly="true" v-for="led in top_row" />
                                                                                </div>
                                                                        </div>
                                                                        <div class="col-md-2 align-self-center bottom-leds">
-                                                                               <input class="led_color" type="hidden" name="[13]"/>
-                                                                               <input class="led_color" type="hidden" name="[12]"/>
+                                                                               <input class="led_color" type="hidden" :name="led" readonly="true" v-for="led in bottom_right_row" />
                                                                        </div>
                                                                </div>
                                                        </div>
                                                        <div class="d-flex justify-content-center">
-                                                               <input class="led_color" type="hidden" name="[8]"/>
-                                                               <input class="led_color" type="hidden" name="[9]"/>
-                                                               <input class="led_color" type="hidden" name="[10]"/>
-                                                               <input class="led_color" type="hidden" name="[11]"/>
+                                                               <input class="led_color" type="hidden" :name="led" readonly="true" v-for="led in aft_row" />
                                                        </div>
                                                </div>
                                                <div class="col-md-3 offset-md-1">
-                                                       <div class="form-group row">
-                                                               <label class="col-sm-2 col-form-label">Alle</label>
-                                                               <div class="col-sm-10">
-                                                                       <input class="led_color" type="text" name="[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]" class="form-control"/>
-                                                               </div>
-                                                       </div>
-                                                       <div class="form-group row">
-                                                               <label class="col-sm-2 col-form-label">Front</label>
-                                                               <div class="col-sm-10">
-                                                                       <input class="led_color" type="text" name="[0, 1, 2, 3]" class="form-control"/>
-                                                               </div>
-                                                       </div>
-                                                       <div class="form-group row">
-                                                               <label class="col-sm-2 col-form-label">Aft</label>
-                                                               <div class="col-sm-10">
-                                                                       <input class="led_color" type="text" name="[8, 9, 10, 11]" class="form-control"/>
-                                                               </div>
-                                                       </div>
-                                                       <div class="form-group row">
-                                                               <label class="col-sm-2 col-form-label">Top</label>
-                                                               <div class="col-sm-10">
-                                                                       <input class="led_color" type="text" name="[4, 5, 6, 7]" class="form-control"/>
-                                                               </div>
-                                                       </div>
-                                                       <div class="form-group row">
-                                                               <label class="col-sm-2 col-form-label">Bottom</label>
-                                                               <div class="col-sm-10">
-                                                                       <input class="led_color" type="text" name="[12, 13, 14, 15]" class="form-control"/>
-                                                               </div>
-                                                       </div>
+                                                       <input-led label="All" name="[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]"></input-led>
+                                                       <input-led label="Front" name="[0, 1, 2, 3]"></input-led>
+                                                       <input-led label="Aft" name="[8, 9, 10, 11]"></input-led>
+                                                       <input-led label="Top" name="[4, 5, 6, 7]"></input-led>
+                                                       <input-led label="Bottom" name="[12, 13, 14, 15]"></input-led>
                                                </div>
                                        </div>
                                </div>
+                               <div id="drive" class="tab-pane" role="tabpanel">
+                                       <div class="cmd_vel_circle"></div>
+                               </div>
                        </div>
                </div>
-               <script src="assets/javascripts/jquery-3.3.1.min.js"></script>
-               <script src="assets/javascripts/popper.min.js"></script>
-               <script src="assets/javascripts/bootstrap.min.js"></script>
-               <script src="assets/javascripts/jquery-ui.min.js"></script>
-               <script src="assets/javascripts/easeljs.min.js"></script>
-               <script src="assets/javascripts/eventemitter2.js"></script>
-               <script src="assets/javascripts/roslib.js"></script>
-               <script src="assets/javascripts/ros2d.js"></script>
-               <script src="assets/javascripts/nav2d.js"></script>
-               <script src="assets/javascripts/keyboardteleop.js"></script>
-               <script src="assets/javascripts/jquery.minicolors.js"></script>
        </body>
+       <script type="text/x-template" id="input-value-template">
+               <div class="input-value">
+                       <label>{{label}}:</label>
+                       <div class="input-group">
+                               <input type=text class="form-control" :value="value" readonly>
+                               <div class="input-group-append" v-if="unit">
+                                       <span class="input-group-text">{{unit}}</span>
+                               </div>
+                       </div>
+               </div>
+       </script>
+       <script type="text/x-template" id="input-led-template">
+               <div class="form-group row">
+                       <label class="col-sm-2 col-form-label">{{label}}</label>
+                       <div class="col-sm-10">
+                               <input type="text" :name="name" class="led_color" readonly="true"/>
+                       </div>
+               </div>
+       </script>
 </html>