From 1fe0debd6474c0368f81159cd6a0451edbc6d381 Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Fri, 16 Mar 2018 18:03:34 -0600 Subject: Added a lot of features to the viz tool --- tools/viz/README.md | 13 -- tools/viz/index.html | 10 ++ tools/viz/survive_viewer.js | 341 +++++++++++++++++++++++--------------------- 3 files changed, 185 insertions(+), 179 deletions(-) delete mode 100644 tools/viz/README.md (limited to 'tools') diff --git a/tools/viz/README.md b/tools/viz/README.md deleted file mode 100644 index 6afbd5c..0000000 --- a/tools/viz/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# How to use - -- Download and install: http://websocketd.com/ -- Build the repo -- Run data_recorder through websocketd like so: - -``` websocketd --port=8080 ./data_recorder``` - -- Navigate to the `index.html` page in this directory on chrome. - -When lighthouses, poses, or angle information is found, it should add it the scene. - - diff --git a/tools/viz/index.html b/tools/viz/index.html index 5085faf..b146b5d 100644 --- a/tools/viz/index.html +++ b/tools/viz/index.html @@ -19,5 +19,15 @@ +
+ +
diff --git a/tools/viz/survive_viewer.js b/tools/viz/survive_viewer.js index f7c6339..3aa2cf7 100644 --- a/tools/viz/survive_viewer.js +++ b/tools/viz/survive_viewer.js @@ -1,4 +1,12 @@ -var sphere, axes; +var objs = {}; +var visible_tolerance = 48000000 / 15; +var downAxes = {}; +var angles = {}; +var ctx; +var canvas; +var oldDrawTime = 0; + +$(function() { $("#toggleBtn").click(function() { $("#cam").toggle(); }); }); function add_lighthouse(idx, p, q) { var group = new THREE.Group(); @@ -37,14 +45,48 @@ function add_lighthouse(idx, p, q) { scene.add(group); // DrawCoordinateSystem(p[0], p[1], p[2], q[0], q[1], q[2], q[3]); } -var downAxes = {}; -var angles = {}; -var ctx; -var canvas; -var oldDrawTime = 0; -var lastWhen = {}; -$(function() { $("#toggleBtn").click(function() { $("#cam").toggle(); }); }); +function recolorTrackers(when) { + for (var key in angles) { + var colors = []; + + for (var lh = 0; lh < 2; lh++) { + var bvalue = {"WW0" : "FF", "TR0" : "00"}; + ctx.strokeStyle = (lh === 0 ? "#FF00" : "#00FF") + bvalue[key]; + + if (angles[key][lh]) + + for (var id in angles[key][lh]) { + var ang = angles[key][lh][id]; + + colors[id] = colors[id] || 0; + + if (ang[0] === undefined || ang[1] === undefined) + continue; + + for (var acode = 0; acode < 2; acode++) { + if (ang[acode][1] < when[key] - visible_tolerance) + continue; + + var augment = 0xf; + if (lh) + augment = augment << 8; + if (acode) + augment = augment << 4; + + colors[id] = colors[id] | augment; + } + } + } + + for (var id in colors) { + if (objs[key]) { + var material = objs[key].sensors[id]; + material.color.setHex(colors[id]); + } + } + } + } function redrawCanvas(when) { oldDrawTime = new Date().getTime(); @@ -95,8 +137,8 @@ function redrawCanvas(when) { for (var id in angles[key][lh]) { var ang = angles[key][lh][id]; - if (ang[0] === undefined || ang[1] === undefined || ang[1][1] < when[key] - 48000000 || - ang[0][1] < when[key] - 48000000) + if (ang[0] === undefined || ang[1] === undefined || ang[1][1] < when[key] - visible_tolerance || + ang[0][1] < when[key] - visible_tolerance) continue; var half_fov = 1.0472 * 2; @@ -115,14 +157,10 @@ function redrawCanvas(when) { } } -var objs = {}; -var sensorGeometry = new THREE.SphereGeometry(.01, 32, 16); -// use a "lambert" material rather than "basic" for realistic lighting. -// (don't forget to add (at least one) light!) - function create_object(info) { + var sensorGeometry = new THREE.SphereGeometry(.01, 32, 16); var group = new THREE.Group(); - group.colors = []; + group.sensors = []; if (info.config && info.config.lighthouse_config) { for (var idx in info.config.lighthouse_config.modelPoints) { var p = info.config.lighthouse_config.modelPoints[idx]; @@ -131,11 +169,11 @@ function create_object(info) { color = 0x00ff00; if (idx === 12) color = 0x0000ff; - var sensorMaterial = new THREE.MeshLambertMaterial({color : color}); + var sensorMaterial = new THREE.MeshBasicMaterial({color : color}); var newSensor = new THREE.Mesh(sensorGeometry, sensorMaterial); newSensor.position.set(p[0], p[1], p[2]); - group.colors[idx] = sensorMaterial; + group.sensors[idx] = sensorMaterial; group.add(newSensor); } } @@ -147,112 +185,136 @@ function create_object(info) { } var timecode = {}; -$(function() { - - function parseLine(msg) { - var s = msg.split(' '); - - var command_mappings = { - "LH_POSE" : function(v) { - return { - type : "lighthouse_pose", - lighthouse : parseInt(v[1]), - position : [ parseFloat(v[3]), parseFloat(v[4]), parseFloat(v[5]) ], - quat : [ parseFloat(v[6]), parseFloat(v[7]), parseFloat(v[8]), parseFloat(v[9]) ] - }; - }, - "POSE" : function(v) { - return { - type: "pose", tracker: v[1], position: [ parseFloat(v[3]), parseFloat(v[4]), parseFloat(v[5]) ], - quat: [ parseFloat(v[6]), parseFloat(v[7]), parseFloat(v[8]), parseFloat(v[9]) ] - } - }, - "CONFIG" : function(v) { - var configStr = s.slice(3).join(' '); - var config = JSON.parse(configStr); - - return { type: "htc_config", config: config } +function parseLine(msg) { + var s = msg.split(' '); + + var command_mappings = { + "LH_POSE" : function(v) { + return { + type : "lighthouse_pose", + lighthouse : parseInt(v[1]), + position : [ parseFloat(v[3]), parseFloat(v[4]), parseFloat(v[5]) ], + quat : [ parseFloat(v[6]), parseFloat(v[7]), parseFloat(v[8]), parseFloat(v[9]) ] + }; + }, + "POSE" : function(v) { + return { + type: "pose", position: [ parseFloat(v[3]), parseFloat(v[4]), parseFloat(v[5]) ], + quat: [ parseFloat(v[6]), parseFloat(v[7]), parseFloat(v[8]), parseFloat(v[9]) ] } - }; - if (command_mappings[s[2]]) { - var rtn = command_mappings[s[2]](s); - rtn.time = parseFloat(s[0]); - rtn.tracker = s[1]; - return rtn; + }, + "CONFIG" : function(v) { + var configStr = s.slice(3).join(' '); + var config = JSON.parse(configStr); + + return { type: "htc_config", config: config } + + }, + 'A' : function(v) { + return { + type: 'angle', sensor_id: parseInt(v[3]), acode: parseInt(v[4]), timecode: parseInt(v[5]), + length: parseFloat(v[6]), angle: parseFloat(v[7]), lighthouse: parseInt(v[8]) } - return {}; + }, + 'LOG' : function(v) { + return { type: "info", msg: s.slice(3).join(' ') } + }, + "I" : function(v) { + return { + type : "imu", + mask : parseInt(v[3]), + timecode : parseInt(v[4]), + accelgyro : [ + parseFloat(v[5]), parseFloat(v[6]), parseFloat(v[7]), parseFloat(v[8]), parseFloat(v[9]), + parseFloat(v[10]) + ] + + }; } - var ws; - if (window.location.protocol === "file:") { - ws = new WebSocket("ws://localhost:8080/ws"); - } else { - ws = new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + - "/ws"); - } - - ws.onopen = function(evt) { - // ws.send("!"); }; - ws.onmessage = function(evt) { - var msg = evt.data; - var obj; - if (msg[0] == "{") - obj = JSON.parse(msg); - else - obj = parseLine(msg); - - // console.log(obj); - if (obj.type === "pose") { - if (objs[obj.tracker]) { - objs[obj.tracker].position.set(obj.position[0], obj.position[1], obj.position[2]); - objs[obj.tracker].quaternion.set(obj.quat[1], obj.quat[2], obj.quat[3], obj.quat[0]); - } - } else if (obj.type === "lighthouse_pose") { - add_lighthouse(obj.lighthouse, obj.position, obj.quat); - } else if (obj.type === "htc_config") { - create_object(obj); - } else if (obj.type === "imu") { - if (objs[obj.tracker]) { - if (!downAxes[obj.tracker]) { - downAxes[obj.tracker] = new THREE.Geometry(); - downAxes[obj.tracker].vertices.push( - new THREE.Vector3(0, 0, 0), - new THREE.Vector3(obj.accelgyro[0], obj.accelgyro[1], obj.accelgyro[2])); - - var line = new THREE.Line(downAxes[obj.tracker], new THREE.LineBasicMaterial({color : 0xffffff})); - objs[obj.tracker].add(line); - } else { - var q = obj.accelgyro; - downAxes[obj.tracker].vertices[1].fromArray(q); - downAxes[obj.tracker].verticesNeedUpdate = true; + if (command_mappings[s[2]]) { + var rtn = command_mappings[s[2]](s); + rtn.time = parseFloat(s[0]); + rtn.tracker = s[1]; + return rtn; + } + return {}; +} + +$(function() { + setTimeout(function() { + var ws; + + if (window.location.protocol === "file:") { + ws = new WebSocket("ws://localhost:8080/ws"); + } else { + ws = new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + + "/ws"); + } + + ws.onopen = function(evt) { + // ws.send("!"); + }; + ws.onmessage = function(evt) { + var msg = evt.data; + var obj; + if (msg[0] == "{") + obj = JSON.parse(msg); + else + obj = parseLine(msg); + + // console.log(obj); + if (obj.type === "pose") { + if (objs[obj.tracker]) { + objs[obj.tracker].position.set(obj.position[0], obj.position[1], obj.position[2]); + objs[obj.tracker].quaternion.set(obj.quat[1], obj.quat[2], obj.quat[3], obj.quat[0]); + } + } else if (obj.type === "info") { + var consoleDiv = $("#console"); + consoleDiv.append(obj.msg + "
"); + consoleDiv[0].scrollTop = consoleDiv[0].scrollHeight; + } else if (obj.type === "lighthouse_pose") { + add_lighthouse(obj.lighthouse, obj.position, obj.quat); + } else if (obj.type === "htc_config") { + create_object(obj); + } else if (obj.type === "imu") { + if (objs[obj.tracker]) { + if (!downAxes[obj.tracker]) { + downAxes[obj.tracker] = new THREE.Geometry(); + downAxes[obj.tracker].vertices.push( + new THREE.Vector3(0, 0, 0), + new THREE.Vector3(obj.accelgyro[0], obj.accelgyro[1], obj.accelgyro[2])); + + var line = + new THREE.Line(downAxes[obj.tracker], new THREE.LineBasicMaterial({color : 0xffffff})); + objs[obj.tracker].add(line); + } else { + var q = obj.accelgyro; + downAxes[obj.tracker].vertices[1].fromArray(q); + downAxes[obj.tracker].verticesNeedUpdate = true; + } } - } - } else if (obj.type === "angle") { - angles[obj.tracker] = angles[obj.tracker] || {}; - angles[obj.tracker][obj.lighthouse] = angles[obj.tracker][obj.lighthouse] || {}; - angles[obj.tracker][obj.lighthouse][obj.sensor_id] = - angles[obj.tracker][obj.lighthouse][obj.sensor_id] || {}; + } else if (obj.type === "angle") { + angles[obj.tracker] = angles[obj.tracker] || {}; + angles[obj.tracker][obj.lighthouse] = angles[obj.tracker][obj.lighthouse] || {}; + angles[obj.tracker][obj.lighthouse][obj.sensor_id] = + angles[obj.tracker][obj.lighthouse][obj.sensor_id] || {}; - angles[obj.tracker][obj.lighthouse][obj.sensor_id][obj.acode] = [ obj.angle, obj.timecode ]; - timecode[obj.tracker] = obj.timecode; - } + angles[obj.tracker][obj.lighthouse][obj.sensor_id][obj.acode & 1] = [ obj.angle, obj.timecode ]; + timecode[obj.tracker] = obj.timecode; + } - // ws.send("!"); - }; + // ws.send("!"); + }; + }, 60); // Hacky, but this gives the server time to restart on CTRL+R }); -////////// -// MAIN // -////////// - // standard global variables -var container, scene, camera, renderer, controls, stats; -var clock = new THREE.Clock(); +var container, scene, camera, renderer, controls; // custom global variables -var cube; $(function() { // initialization init(); @@ -272,23 +334,16 @@ init() { /////////// scene = new THREE.Scene(); - //////////// - // CAMERA // - //////////// - - // set the view size in pixels (custom or according to window size) - // var SCREEN_WIDTH = 400, SCREEN_HEIGHT = 300; var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; // camera attributes var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.01, FAR = 200; + // set up camera camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); camera.up = new THREE.Vector3(0, 0, 1); + // add the camera to the scene scene.add(camera); - // the camera defaults to position (0,0,0) - // so pull it back (z = 400) and up (y = 100) and set the angle towards the - // scene origin camera.position.set(5, 2, 5.00); camera.lookAt(scene.position); @@ -297,52 +352,24 @@ init() { ////////////// renderer = new THREE.WebGLRenderer({antialias : true}); - renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); // attach div element to variable to contain the renderer container = document.getElementById('ThreeJS'); - // alternatively: to create the div at runtime, use: - // container = document.createElement( 'div' ); - // document.body.appendChild( container ); // attach renderer to the container div container.appendChild(renderer.domElement); - //////////// - // EVENTS // - //////////// - - /* - // automatically resize renderer - THREEx.WindowResize(renderer, camera); - // toggle full-screen on given key press - THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) }); -*/ - ////////////// - // CONTROLS // - ////////////// - // move mouse and: left click to rotate, // middle click to zoom, // right click to pan controls = new THREE.OrbitControls(camera, renderer.domElement); - /////////// - // LIGHT // - /////////// - // create a light var light = new THREE.PointLight(0xffffff); light.position.set(0, 5, 0); scene.add(light); - var ambientLight = new THREE.AmbientLight(0x111111); - // scene.add(ambientLight); - var floorTexture = new THREE.ImageUtils.loadTexture('images/checkerboard.jpg'); - floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping; - floorTexture.repeat.set(10, 10); - // DoubleSide: render texture on both sides of mesh var floorMaterial = new THREE.MeshBasicMaterial({color : 0x000000, opacity : 0.15, transparent : true, side : THREE.FrontSide}); var floorGeometry = new THREE.PlaneGeometry(10, 10); @@ -351,35 +378,17 @@ init() { scene.add(floor); - ///////// - // SKY // - ///////// - - // recommend either a skybox or fog effect (can't use both at the same time) - // without one of these, the scene's background color is determined by - // webpage background - var skyBoxGeometry = new THREE.CubeGeometry(50, 50, 50); var skyBoxMaterial = new THREE.MeshBasicMaterial({color : 0x888888, side : THREE.BackSide}); var skyBox = new THREE.Mesh(skyBoxGeometry, skyBoxMaterial); scene.add(skyBox); - - // fog must be added to scene before first render - // scene.fog = new THREE.FogExp2(0xffffff, 0.025); } function animate() { requestAnimationFrame(animate); + recolorTrackers(timecode); render(); - update(); redrawCanvas(timecode); } -function update() { - // delta = change in time since last call (in seconds) - var delta = clock.getDelta(); - - // controls.update(); - } - function render() { renderer.render(scene, camera); } -- cgit v1.2.3