Closed nakulcr7 closed 9 years ago
The riggedHand.meshAdded can occasionally take quite a lot of time. If you want your application to not do anything before it's fired, maybe you should wait for it to happen first (and present a loading animation in the meanwhile). You should probably wait until both of them are fired and then execute a callback.
Since JavaScript is single-threaded, this can easily be achieved by setting initialization flags in both the callbacks and then running the final callback that just checks if both of the flags are set.
// Store all the initialization data that we want to use in one callback.
var inits = {actionData: false, meshAdded: false};
// Finalization callback that won't execute finalization until we have all the data.
function attemptFinishingInitialization() {
if (inits.actionData && inits.meshAdded) {
$('$display').html(inits.actionData);
}
}
// In callbacks, store the init state and call attemptFinishingInitialization:
socket.on('action', function(data) {
inits.actionData = data;
attemptFinishingInitialization();
});
controller.on('riggedHand.meshAdded', function(handMesh, leapHand){
handMesh.material.opacity = 1;
handMesh.material.color.set('#7b4b2a');
handMesh.material.ambient = handMesh.material.color;
inits.meshAdded = true;
attemptFinishingInitialization();
});
Thank you for your reply. I tried your suggestion, it still isn't working. The jquery part and the hand visualization aren't working independently of each other. For example, if I comment out the visualization part(seen below), data is displayed in the
<body>
<div id="display"><span id="direction">undefined</span></div>
</body>
<script type="text/javascript">
var socket = io();
socket.on('action', function(data) {
$('$display').html(data);
});
/*var controller = new Leap.Controller;
(controller).use('riggedHand', {
scale: 1.5
})
.connect();
controller.on('riggedHand.meshAdded', function(handMesh, leapHand){
handMesh.material.opacity = 1;
handMesh.material.color.set('#7b4b2a');
handMesh.material.ambient = handMesh.material.color;
});*/
</script>
This is the server-side code.
var express = require('express'),
app = express(),
http = require('http').Server(app),
io = require('socket.io')(http),
Leap = require('leapjs');
var action = 'Stop';
app.use(express.static('public'));
app.get('/', function(req, res) {
res.sendFile('./public/index.html');
});
http.listen(4000, function() {
console.log('listening on port 4000');
});
var controller = new Leap.Controller();
controller.connect();
io.on('connection', function(socket) {
controller.on('frame', function(frame) {
socket.emit('action', action);
if(frame.hands.length < 1) {
action = 'Stop';
}
else {
getCommand(frame.hands[0]);
}
});
});
function getCommand(hand){
var x_axis = hand.palmPosition[0];
var y_axis = hand.palmPosition[1];
var z_axis = hand.palmPosition[2];
var power = 0;
if( y_axis <= 100 ) {
power = 0;
}
else {
power = 1;
}
if( Math.abs(x_axis) > Math.abs(z_axis) ) {
if( x_axis > 100 )
action = 'Right';
else if( x_axis < -100 )
action = 'Left';
else
action = 'Stop';
}
else {
if( z_axis > 50 )
action = 'Reverse';
else if( z_axis < -50 )
action = 'Forward';
else
action = 'Stop';
}
console.log(action);
}
If that's the case, I wonder if there's anything printed in the console and/or network panel in dev tools? If you comment one part out, does the other work fine? If so, we need to dig deeper with the help of a debugger.
Below are the screenshots.
So if my understanding is correct: you are maintaining two LeapJS connections simultaneously, one on in Node and one on the client. If so, be sure to connect with background mode on, so that both work even without focus. (new Leap.Controller({background: true})
).
Besides that, I might suggest simplifying your set up (what happens if you only use one or the other independently?) Or piping the commands the other direction (from the browser through sockerIO to your robot).
Hey pehrlich! {background:true} worked. You're right, piping the commands in the other direction simplifies my setup. Thank you :)
I am working on making an interface for a Leap motion controlled robot. From the server side node.js, I am emitting an event 'action' which contains the data to be displayed on a HTML page. I am using leapjs-rigged-hand for visualization (https://github.com/leapmotion/leapjs-rigged-hand)
Shown above is the relevant part of the code. The problem is that socket callback works only before the first "riggedHand.meshAdded" event is fired.
How do I make them work simultaneously?
Thank you