cyberbotics / webots

Webots Robot Simulator
https://cyberbotics.com
Apache License 2.0
3.26k stars 1.7k forks source link

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

Closed Adman closed 2 years ago

Adman commented 3 years ago

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

https://user-images.githubusercontent.com/865063/112186121-221b4300-8c01-11eb-980f-035807717915.mp4

System

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 commented 3 years ago

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

Adman commented 3 years ago

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

omichel commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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

Adman commented 3 years ago

@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 commented 3 years ago

@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 commented 2 years ago

@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 commented 2 years ago

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)
BenjaminDeleze commented 2 years ago

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:

Adman commented 2 years ago

@BenjaminDeleze We have similar problem with robots when they are being relocated while running at high speed - https://github.com/RoboCupJuniorTC/rcj-soccer-sim/issues/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 commented 2 years ago

I will have a look

BenjaminDeleze commented 2 years ago

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

BenjaminDeleze commented 2 years ago

@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 commented 2 years ago

We tried several different values https://github.com/RoboCupJuniorTC/rcj-soccer-sim/issues/130#issuecomment-1106901965 , but the problem still persists. Are your robots running at high speed (i.e. 10) ?

BenjaminDeleze commented 2 years ago

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 commented 2 years ago

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