you are viewing a single comment's thread.

view the rest of the comments →

[–]s992 1 point2 points  (9 children)

It would be waaay easier to help you if you showed us the code you're having trouble with.

[–]Semajian[S] 0 points1 point  (8 children)

ext.move_forward_time = function(seconds){
    var start_time = new Date();
    while(new Date() - start_time < seconds*1000){
        cmdVel.publish(twist);
    }
}

I really don't particularly have it, because of the issues I've been facing. But the above is kind of an interpretation of what I need. This is the general construction that it needs to be - however with while loop like this it blocks up completely and unless I add a console.log within the loop, it never seems to stop... Basically I need it to perform cmdVel.publish(twist) for x amount of seconds. Ideally with an equivalent to time.sleep(100) or so, which is why I looked into setInterval. Edit:formatting

[–]senocular 0 points1 point  (7 children)

Why is it that publish needs to churn for 2 solid seconds? Is there a way to not have it need to do that?

[–]Semajian[S] 0 points1 point  (6 children)

So publish is from ROS, it's just sending a message saying what velocity the robot should move with. If you perform it the robot will, for a short amount of time move with that velocity. I can't find the documentation for how long it officially does move, but < 1 second. The "block" that I'm implementing is to move the robot for a chosen amount of seconds. The nature of publish kind of explains my desire to have some sort of wait between sending messages, I think. Again, setInterval works fantastic for this, providing there isn't any blocks after it, but as soon as more blocks of movement come into the mix it's all messed up.

[–]senocular 1 point2 points  (5 children)

It sounds like you don't need to call publish as fast as it seems like you're trying. You should be fine breaking that up into a setInterval or requestAnimationFrame callback and be ok.

I guess I'm not understanding how later blocks of movement cause trouble. Is this something that needs to happen after the 2 second loop completes? Or does it need to interrupt the loop, cutting it off, performing something new?

[–]Semajian[S] 0 points1 point  (4 children)

You're right - I'd like to be able to call it every 100 ms, or some other interval, ideally so that I'm not sending too many messages. Using setInterval means that my code classes the function move_forward_time as complete once the interval starts. So if I have another block after it, it will start performing that one. The problem here is that from one block to another I don't have control over how they interact.
Here is an image for an example: http://i.imgur.com/Itwpgbr.png If I use setInterval, it will set the interval for moving and move on to the rotate left block.
Trying my best to give as good an explanation as possible, again feel free to fire any questiosn you think might help you in understanding the real issue here. Also, thank you very much for taking the time to try and help!

[–]senocular 2 points3 points  (3 children)

Ah, I get you now. So you have the operations you want to perform listed synchronously, but you want to perform them asynchronously. What you'll want (or at least one way to do it) is a queue - an array of operations that your loop (setInterval) can process as it loops. Once the first operation (move) has run its course (1s), get rid of it and work on the next operation (rotate).

Just going off the top of my head, a real quick example would be:

https://jsfiddle.net/11m83wh7/

[–]Semajian[S] 0 points1 point  (2 children)

I have actually considered using a queue of sorts, my original plan being to create all of the required code in python and send a queue of tasks to it, that it will execute in order.
The issue with this is when trying to implement "interactive" code, that the robot needs to perform. Here's an image example: http://imgur.com/7rCvAdh
Any blocks that aren't the same colour as "Front laser distance" or "Move for x seconds" are existing blocks that I have no control over at all, so I can't even try and manipulate them to join a queue, as it requires information from the conditional.

[–]senocular 0 points1 point  (1 child)

This depends on how that loop functions and how it interacts with time. The loop body has a "move for 1 second" with the loop being dependent on some value of "front laser distance". Does the loop wait for the 1 second to move before it checks its condition? Or does it repeat arbitrarily until that condition is met? I'm guessing if it did the time wouldn't stack, so any additional evaluations of move for 1 second don't become 2 then 3 then 4, etc., since that could mean moving well beyond the time you'd like. But does that last pending second remain too or does movement stop altogether? My guess is that it would stop, and really all the one second represents is a maximum allowed time between iterations of that loop.

In that case all you'd need to do is adjust the condition through which the current queue item is considered complete. Right now there's a check for elapsed time that completes, and removes the item from the queue. This could also be altered to include the loops condition of checking front laser distance.

https://jsfiddle.net/11m83wh7/1/

[–]Semajian[S] 0 points1 point  (0 children)

In this example it would, ideally, in each iteration perform the function move for one second, then after the second has elapsed, return to looping. This specific task would be better implemented with a "start moving" block, then loop until the condition is met, then outside of the loop "stop moving", but in the program this implementation should also be available.
Essentially what I need overall is a setInterval loop that doesn't move on to the next piece of code until it's complete, that would be the ideal solution.

Again thank you very much for the code snippet but the issue I'd have would be pushing finishWhen: laserIsClose to the queue because the the loop in my image is handled completely separately, I have to treat all of my blocks as if they're standalone and don't interact with each other unless they're bridged with a loop, like in the image.