www: use vue.js-components to avoid duplicates
[ros_wild_thumper.git] / www / assets / javascripts / application.js
1 function init() {
2         var ros = new ROSLIB.Ros();
3         ros.connect('ws://wildthumper:9090');
4         var isDragging = false;
5
6         ros.on('connection', function() {
7                 information.alerts.push({message: "Connected to websocket server.", success: true});
8         });
9
10         ros.on('error', function(error) {
11                 information.alerts.push({message: "Error connecting to websocket server.", danger: true});
12         });
13
14         ros.on('close', function() {
15                 information.alerts.push({message: "Connection to websocket server closed.", info: true});
16         });
17
18         //tfClient.subscribe('base_link', function(tf) {
19         //      var now = new Date();
20         //      $("#pose").text(now.toLocaleTimeString() + ": (" + tf.translation.x + ", " + tf.translation.y + ")");
21
22         //      robotMarker.x = tf.translation.x;
23         //      robotMarker.y = -tf.translation.y;
24         //      robotMarker.rotation = viewer2D.scene.rosQuaternionToGlobalTheta(tf.rotation);
25         //});
26         var poseTopic = new ROSLIB.Topic({ros: ros, name: '/robot_pose', messageType: 'geometry_msgs/Pose'});
27         var sensorTopic = new ROSLIB.Topic({ros: ros, name: '/sensors', messageType: 'wild_thumper/Sensor'});
28         var batteryTopic = new ROSLIB.Topic({ros: ros, name: '/battery', messageType: 'sensor_msgs/BatteryState'});
29         var ledStripeTopic = new ROSLIB.Topic({ros: ros, name: '/led_stripe', messageType: 'wild_thumper/LedStripe'});
30         var cmdVelTopic = new ROSLIB.Topic({ros: ros, name: '/teleop/cmd_vel', messageType: 'geometry_msgs/Twist'});
31
32         poseTopic.subscribe(function(message) {
33                 var now = new Date();
34                 $("#pose").text(now.toLocaleTimeString() + ": (" + message.position.x + ", " + message.position.y + ")");
35         });
36
37         sensorTopic.subscribe(function(message) {
38                 sensors.light = message.light;
39                 sensors.temp = message.temp.toFixed(1);
40                 sensors.humidity = message.humidity;
41                 sensors.pressure = message.pressure.toFixed(1);
42                 sensors.co = message.co;
43         });
44
45         batteryTopic.subscribe(function(message) {
46                 power.voltage = message.voltage.toFixed(1);
47                 power.current = message.current.toFixed(1);
48         });
49
50         viewer2D = new ROS2D.Viewer({
51                 divID: 'map',
52                 width: 640,
53                 height: 480,
54                 background: "#efefef"
55         });
56         $('#map')
57         .bind('mousewheel', function(e) {
58                 if (e.originalEvent.wheelDelta/120 > 0) {
59                         viewer2D.scaleToDimensions(10, 10)
60                 } else {
61                         viewer2D.scaleToDimensions(5, 5)
62                 }
63         })
64         .mousedown(function() {
65                 isDragging = true;
66                 mousePreX = undefined;
67                 mousePreY = undefined;
68         })
69         .mouseup(function() {
70                 isDragging = false;
71         })
72         .mousemove(function(event) {
73                 if (isDragging) {
74                         if (mousePreX != undefined && mousePreY != undefined) {
75                                 var diffX = event.pageX - mousePreX;
76                                 var diffY = event.pageY - mousePreY;
77                                 console.log("Moving viewer2D by " + diffX + ", " + diffY);
78                                 viewer2D.shift(diffX, diffY);
79                         }
80                         mousePreX = event.pageX;
81                         mousePreY = event.pageY;
82                 }
83         });
84
85         // Setup the nav client.
86         NAV2D.OccupancyGridClientNav({
87                 ros : ros,
88                 rootObject : viewer2D.scene,
89                 viewer : viewer2D,
90                 serverName : '/move_base'
91         });
92
93         // Initialize the teleop.
94         teleop = new KEYBOARDTELEOP.Teleop({
95                 ros : ros,
96                 topic : '/teleop/cmd_vel'
97         });
98
99         // Create a UI slider using JQuery UI.
100         $('#speed-slider').slider({
101                 range : 'min',
102                 min : 0.10,
103                 max : 1.0,
104                 step : 0.05,
105                 value : 0.5,
106                 slide : function(event, ui) {
107                         // Change the speed label.
108                         speed_label.speed = ui.value;
109                         // Scale the speed.
110                         teleop.scale = (ui.value * 2);
111                 }
112         });
113
114         // Set the initial speed.
115         teleop.scale = ($('#speed-slider').slider('value') * 2);
116
117         new Vue({
118                 el: '#lights',
119                 data: {
120                         front_row: ["[0]", "[1]", "[2]", "[3]"],
121                         top_row: ["[7]", "[6]", "[5]", "[4]"],
122                         aft_row: ["[8]", "[9]", "[10]", "[11]"],
123                         bottom_left_row: ["[14]", "[15]"],
124                         bottom_right_row: ["[13]", "[12]"],
125                 }
126         })
127         $('.led_color').minicolors({
128                 control: 'wheel',
129                 format: 'rgb',
130                 defaultValue: '#000000',
131                 change: function(value) {
132                         var rgb = $(this).minicolors('rgbObject');
133                         var nums = jQuery.parseJSON($(this).prop("name"));
134                         var msg = new ROSLIB.Message({
135                                 leds: []
136                         });
137                         jQuery.each(nums, function(i, num) {
138                                 msg["leds"].push({
139                                         num: num,
140                                         red: parseInt(rgb.r*127/255),
141                                         green: parseInt(rgb.g*127/255),
142                                         blue: parseInt(rgb.b*127/255)
143                                 })
144                         });
145                         ledStripeTopic.publish(msg);
146                 }
147         });
148
149         function setSpeed(trans, rot) {
150                 var msg = new ROSLIB.Message({
151                         linear: {
152                                 x : trans,
153                                 y : 0,
154                                 z : 0
155                         },
156                         angular: {
157                                 x : 0,
158                                 y : 0,
159                                 z : rot
160                         },
161                 });
162                 cmdVelTopic.publish(msg);
163         }
164
165         $('.cmd_vel_circle')
166         .bind('mousedown touchstart', function(e) {
167                 isDragging = true;
168         })
169         .bind('mouseup touchend mouseleave', function(e) {
170                 isDragging = false;
171                 setSpeed(0, 0);
172         })
173         .bind('mousemove touchmove', function(e) {
174                 if (isDragging) {
175                         // absolute click position
176                         var X,Y;
177                         if (e.originalEvent.touches) {
178                                 X = e.originalEvent.touches[0].pageX;
179                                 Y = e.originalEvent.touches[0].pageY;
180                         } else {
181                                 X = e.pageX;
182                                 Y = e.pageY;
183                         }
184                         // relative click position
185                         var Xrel = X - this.offsetLeft - $(this).width()/2; 
186                         var Yrel = Y - this.offsetTop - $(this).height()/2; 
187                         // scale to -1..+1
188                         var trans = -Yrel / ($(this).height()/2);
189                         var rot = -Xrel / ($(this).width()/2);
190                         setSpeed(trans, rot*3);
191                 }
192         });
193
194         information = new Vue({
195                 el: '#information',
196                 data: {
197                         alerts: [],
198                 },
199                 methods: {
200                         classObject: function(id) {
201                                 return {
202                                         "alert-success": this.alerts[id].success,
203                                         "alert-danger": this.alerts[id].danger,
204                                         "alert-info": this.alerts[id].info
205                                 }
206                         }
207                 }
208         })
209
210         sensors = new Vue({
211                 el: '#sensors',
212                 data: {light: '', temp: '', humidity: '', pressure: '', co: ''}
213         })
214
215         power = new Vue({
216                 el: '#power',
217                 data: {
218                         voltage: '',
219                         current: '',
220                 }
221         })
222
223         speed_label = new Vue({
224                 el: '#speed-label',
225                 data: {
226                         speed: $('#speed-slider').slider('value'),
227                 }
228         })
229
230 }
231
232 Vue.component('input-value', {
233         template: '#input-value-template',
234         props: ['value', 'label', 'unit']
235 })
236
237 Vue.component('input-led', {
238         template: '#input-led-template',
239         props: ['name', 'label']
240 })