Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SoccerBall is moving after setting its position and resetting velocity #2899

Closed
Adman opened this issue Mar 23, 2021 · 20 comments · Fixed by #2991 or #4070
Closed

SoccerBall is moving after setting its position and resetting velocity #2899

Adman opened this issue Mar 23, 2021 · 20 comments · Fixed by #2991 or #4070
Assignees
Labels
bug Something isn't working
Milestone

Comments

@Adman
Copy link
Contributor

Adman commented Mar 23, 2021

Describe the Bug
When we manually set the position of the ball and subsequently reset its velocity, ball keeps moving very slowly. Seems like some force is not reset or paused in background while moving the object.

Steps to Reproduce

  1. Have a SoccerBall object
  2. Change its position and reset velocity
    a) self.getFromDef("BALL").getField("translation").setSFVec3f([x, y, z])
    b) self.getFromDef("BALL").setVelocity([0, 0, 0, 0, 0, 0])
  3. Check the velocity of the ball

Expected behavior
The ball should have zero velocity (not moving at all).

Video

soccer.mp4

System

  • Operating System: Linux Ubuntu 20.04

Additional context
If I print the velocity using getVelocity() method after setting it to zero, the velocity is non-zero.

Workaround
There is a workaround to tackle this problem: set the velocity to zero in two subsequent steps.

@omichel
Copy link
Member

omichel commented Mar 23, 2021

Instead of setting the velocity to 0, you should reset the physics of the ball.

@Adman
Copy link
Contributor Author

Adman commented Mar 23, 2021

I tried calling reset physics, but that had no effect on velocity the same problem occurs.

@omichel
Copy link
Member

omichel commented Mar 24, 2021

Which Ball proto do you use? Some of them have an offset for the center of mass to provide some randomness in the motion, which makes that when you move them and want the ball to stay still you should also reset the rotation field of the ball, so that the offset of the center of mass will be vertical and won't generate an initial motion. Note: you may also remove this offset to the center of mass from the ball proto if not needed. Finally, you may also increase the Damping of the ball.

@Adman
Copy link
Contributor Author

Adman commented Mar 24, 2021

The SoccerBall.proto has #VRML_SIM R2021a utf8 at the beginning -- not sure if this is what you asked for. I have also tried setting the rotation to [0, 1, 0, 0] without success. After showing the center of mass, it seems like there is no offset from center.
Also, adding Damping to children node of the ball with linear=1 and angular=1 did not help. I tried also reordering the set translation, set rotation and reset physics calls.

@omichel
Copy link
Member

omichel commented Mar 31, 2021

I checked and the SoccerBall.proto has no offset for the center of mass, so it shouldn't be a problem.
I just tested this on the Robocup humanoid league setup and as soon as I call resetPhysics() on the ball, it stops moving immediately. There is not need to set velocity to 0.

@Adman
Copy link
Contributor Author

Adman commented Apr 2, 2021

Interesting. I'm using following code to move the ball:

ball_translation_field = self.getFromDef("BALL").getField("translation")
ball_translation_field.setSFVec3f([x, y, z])
self.getFromDef("BALL").resetPhysics()

And still does not work. :-/

@stefaniapedrazzi stefaniapedrazzi added more information needed Additional information about the issues are needed bug Something isn't working and removed more information needed Additional information about the issues are needed labels Apr 19, 2021
@stefaniapedrazzi
Copy link
Member

stefaniapedrazzi commented Apr 19, 2021

I can reproduce the issue.

The problem is that the resetPhysics instruction is executed immediately as received by Webots, but the setSFVec3f instruction is executed at the end of the step. This means that if the two instructions are called consecutively, the ball position will be changed after resetting the physics.

A workaround that can be applied on the controller side is to reset the physics in the next simulation step, i.e. calling self.step(timestep) just after the setSFVec3f and before the resetPhysics instructions.

And I will fix this in the Webots code.

@stefaniapedrazzi
Copy link
Member

Should be fixed in #2991.
The fix will be available in the nightly build of R2021a rev1 starting from tomorrow.

@Adman
Copy link
Contributor Author

Adman commented Oct 12, 2021

@stefaniapedrazzi I just tested this and seems like it did not resolve the issue :/ The ball is still moving after being moved by supervisor.

@omichel
Copy link
Member

omichel commented Oct 13, 2021

@Adman: can you please upload a simplified project (a simple world with just one ball) and a supervisor process that shows the problem. If we can reproduce the problem, we will try to fix it.

@Adman
Copy link
Contributor Author

Adman commented Nov 18, 2021

@omichel Sorry for late reply. Here's the simplified project just with the ball and supervisor, who moves the ball to a random position every 6 seconds.

moving_ball_example.zip

@omichel
Copy link
Member

omichel commented Nov 19, 2021

Thank you for this. I could reproduce the problem.
It seems the collision detection is disabled for one step after the ball is moved, which causes the ball to sink into the ground and be repulsed at the next time step when the collision detection is enabled again. This creates a reaction forces that moves the ball randomly, hence the motion of the ball we can observe. This is clearly a bug in Webots.

Meanwhile, I found a little trick to minimize the reaction motion and almost fix the problem in your example. The trick is simply to reset twice the ball position and physics:

import random
from controller import Supervisor

sup = Supervisor()
ball = sup.getFromDef("BALL")
time = 1

while sup.step(64) != -1:
    time += 64 / 1000.0

    if int(time % 6) == 0:
        time += 1
        # move the ball
        x = random.uniform(-0.6, 0.6)
        z = random.uniform(-0.5, 0.5)
        ball_translation_field = ball.getField("translation")
        translation = ball_translation_field.getSFVec3f()
        print(translation)
        for i in range(2):
            ball_translation_field.setSFVec3f([x, translation[1], z])
            ball.resetPhysics()
            sup.step(64)

@omichel omichel reopened this Nov 19, 2021
@BenjaminDeleze
Copy link

I can reproduce this issue but not systematically.
When it bugs, I agree that it is because the contact point between the floor and the ball is not computed at all during one step.

But sometimes it works perfectly well.

Some observations so far:

  • I tested both on Windows 10 and Ubuntu 20. Even so I managed to observe the "good" behaviour on both OS, it works better on Ubuntu (1/3 large approximation) than on Windows (maybe 1/20).
  • The number of optimalThreadCount does not seem to have an impact. I managed to reproduce both behavior with 1 and 8 threads.
  • The condition that causes the bug to occur or not seems to be determined at the time of the loading of webots, or at least at the execution of the first world. I think that because once webots is launched, the behaviour is fixed for all the simulations played in this instance of webots: if the first run bugs, all the subsequent will bug (reset, reload or load another world), same goes if the behavior is correct.

@Adman
Copy link
Contributor Author

Adman commented Apr 19, 2022

@BenjaminDeleze We have similar problem with robots when they are being relocated while running at high speed - robocup-junior/rcj-soccersim#130 . Do you think it could be related to this issue? We tested the workaround by resetting the physics in two consecutive steps, which helped to reduce the problem.

@BenjaminDeleze
Copy link

I will have a look

@BenjaminDeleze
Copy link

I can reproduce the bug, but I am not sure it is related to this issue. I will continue to investigate

@BenjaminDeleze
Copy link

@Adman I made some tests on my side and I don't think it is a bug of the reset but more a problem of timestep and collision. Anyway, I found a quick fix by changing the z-value of my robot such that it is already in contact with the floor when relocating it.
I checked your code a bit and I think that changing the value of OBJECT_DEPTH (https://github.com/RoboCupJuniorTC/rcj-soccer-sim/blob/2278b6d48b612231d27884aa013389be6c5a84c9/controllers/rcj_soccer_referee_supervisor/referee/consts.py#L41) to 0.0375 for example could do the trick.
Can you try this and tell me if it works?

@Adman
Copy link
Contributor Author

Adman commented Apr 22, 2022

We tried several different values robocup-junior/rcj-soccersim#130 (comment) , but the problem still persists. Are your robots running at high speed (i.e. 10) ?

@BenjaminDeleze
Copy link

BenjaminDeleze commented Apr 25, 2022

yes, I tested it with a speed of 10.
I made some additional tests and indeed it does not work with the released version of Webots but it works with the latest nightly build.
Can I ask you to test it again (with the value of 0.0375) but with one of the nightly build or by building Webots from the source on the master branch?

@Adman
Copy link
Contributor Author

Adman commented Apr 28, 2022

We tested it and according to @RichoM it works better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment