Jump to content

Problem with setTimeOut and setLinearVelocity


Batucrion
 Share

Recommended Posts

So hello,

I am working on a maze game project. There are two players and both of the players send 2 velocity data as i try to simulate the players like a line follower robot(left motor and right motor). I use Cannonjs to create a heightmap impostor as the maze and 2 sphere impostors as the players. I move the players inside the maze as one of them tries to catch the other. Data is communicated with websocket. When players send 2 velocity data(left motor and right motor) i send them back their positions and an array of 180 distances like a view so they can locate eachother in the maze and decide where to go. So i move each of them like this:

left_motor, right_motor as the velocities one of the players,

i calculate angle with motors and use the angle for x_vel and z_vel,

linear_vel = (left_motor + right_motor)/2

player.physicsImpostor.setLinearVelocity(new BABYLON.Vector3(x,0,z))

setTimeout(function(){

    player.physicsImpostor.setLinearVelocity(new BABYLON.Vector3(0,0,0))

}, 10)

and when sending message back to players i put a setTimeout(sendmessage(player1, player2), 50)

so when i create a test game and set players' velocities to 10 for both motors and print players' positions everytime players send new values, i realised that the difference between positions of both players change by 10 and sometimes 20.

This happens for both players and it does not happen at the same time to both of them.

I use a password system so i am sure a player's data does not get sent over to other player.

I tried to increase the timeout on send message to 1000 and that made no difference.

I checked that linear_vel is always 10 so it never gets doubled.

I am curious about the reason why it is sometimes 20 sometimes 10? Is it some weird interaction between setTimeout and setLinearVelocity?

Link to comment
Share on other sites

Hi B!  Welcome to the forum.  Not easy to troubleshoot this... for forum helpers.  Still, we try.

player.physicsImpostor.setLinearVelocity(new BABYLON.Vector3(0,0,0))  [ Sidenote:  Can be done with...  player.physicsImpostor.setLinearVelocity(BABYLON.Vector3.Zero())  ]

The symptom you describe... COULD be caused by THAT line... being missed, sometimes.

But perhaps, if a player missed a STOP MOVEMENT command... it would keep going forever and would not stop at 20.

I dunno.  It just "feels" like... the first STOP command is sometimes missed, and the NEXT one (IS there a next one... for a single move?  Unlikely)... is used instead.

Just a hunch - based upon the fact that the unwanted value is exactly double the wanted value.

If you ONLY run X motor, or ONLY run Z motor... does the distance stay at 10... more often?  ie.  Is the unwanted 20 value MORE likely... when BOTH X & Z velocities are activated?

(thx for info).  I'll keep thinking.  Weird problem.  Can you create a "server simulator" so we could try to get your project into the BabylonJS playground?  It seems... we could hang some function on the renderLoop... that "sims the server" for the rest of the playground scene.  (fake message sends, etc).  I think that would help us figure this out.  Maybe.

Stay tuned for more comments from others... let's see what shows-up in the minds of our friends.  :)

Link to comment
Share on other sites

I was designing this as a competition so players actually run their algorithms on their computers so i have not implemented it into a small simulation since i have like 4  days until deadline :D

However its a really basic scene with a height map(i do not know how to use heightmaps in playground except the world map one in the tutorial) with either ground or a wall and 2 spheres moving inside it. Movements do not happen until both players send their motor values so its event based movement. Both players keep sending motor values (4-5 times per second) for like 3 minutes. I actually do not know how to make a playground that changes when an event happens :/

I tried the vector3.zero one didn't change anything unfortunately.

I also tried to put console.log before, after the movement section and inside the setTimeout and have not found any clue. It looks like it triggers once every time a player sends data.

When i looked at the frequency of 20's i saw that even though the code is exactly the same player2 had more 20's while player1 had more 10's. 10 is the normal movement. In my tests player1 was moving in x axis while player2 was moving in the z.

Edited by Batucrion
Added more info
Link to comment
Share on other sites

You can see the exact code below that triggers when someone with the right password sends a message to cat's websocket. For the player(cat) that is chasing the other one(rat):

angular is for how much the angle is going to change when the mesh moves. game["players"]["cat"]["mesh"] holds the actual mesh, game["players"]["cat"]["mesh"].physicsImpostor is the Impostor, game["players"]["cat"]["angle"] is the angle the mesh is facing, data is the values player sends.

Quote

            var right_velocity = parseFloat(data["right_velocity"])
            var left_velocity = parseFloat(data["left_velocity"])
            var angular;

            var linear = (right_velocity + left_velocity)/2
            if(left_velocity > right_velocity){
              angular = ((left_velocity - right_velocity))*Math.PI/180
            }
            else if(left_velocity < right_velocity){
              angular = (right_velocity - left_velocity)*Math.PI/180
            }
            else{
              angular = 0;
            }
            game["players"]["cat"]["mesh"].rotation.y = -angular;
            game["players"]["cat"]["angle"] += angular;
            game["players"]["cat"]["angle"] %= 2*Math.PI
            var x = Math.cos(game["players"]["cat"]["angle"])*linear;
            var z = Math.sin(game["players"]["cat"]["angle"])*linear;


            game["players"]["cat"]["mesh"].physicsImpostor.setLinearVelocity(new BABYLON.Vector3(x,0,z))
            setTimeout(function(){
              game["players"]["cat"]["mesh"].physicsImpostor.setLinearVelocity(BABYLON.Vector3.Zero())
            }, 10)

 

Edited by Batucrion
Typo, Info
Link to comment
Share on other sites

I do not know how frequent players are going to send data, so if i remove the timeout, mesh will keep moving so both players are not going to move same amount per velocity data sent. Movements are turn based so when player1 sends data and moves, player1 cant move again before player2 moves. At least thats what im trying to make.

Link to comment
Share on other sites

So, i've been experimenting for sometime and i realized that if i change the delay on setTimeout the second value changes. So when i made the setTimeout 50, i got 2 values again. However this time one was 10 the other one was 26~. I am not sure what to think anymore.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...