cyberbotics / webots

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

Accelerometer return incorrect reading #1693

Closed MauroMombelli closed 4 years ago

MauroMombelli commented 4 years ago

Describe the Bug Adding accelerometer to a child does not apply the correct rotational accelerations.

Steps to Reproduce code:

int main(int argc, char **argv) {
  wb_robot_init();
  double time_step = wb_robot_get_basic_time_step();
  WbDeviceTag motor = wb_robot_get_device("motor");

  float w_y = (3.14/4);// 45°/s
  wb_motor_set_position(motor, INFINITY);
  wb_motor_set_velocity(motor, w_y);

  WbDeviceTag accelerometerC = wb_robot_get_device("accC");
  wb_accelerometer_enable(accelerometerC, time_step);
  WbDeviceTag accelerometer1 = wb_robot_get_device("accX");
  wb_accelerometer_enable(accelerometer1, time_step);
  WbDeviceTag accelerometer2 = wb_robot_get_device("accY");
  wb_accelerometer_enable(accelerometer2, time_step);
  WbDeviceTag accelerometer3 = wb_robot_get_device("accZ");
  wb_accelerometer_enable(accelerometer3, time_step);

  WbDeviceTag accelerometerC2 = wb_robot_get_device("accC2");
  wb_accelerometer_enable(accelerometerC2, time_step);
  WbDeviceTag accelerometerX2 = wb_robot_get_device("accX2");
  wb_accelerometer_enable(accelerometerX2, time_step);
  WbDeviceTag accelerometerY2 = wb_robot_get_device("accY2");
  wb_accelerometer_enable(accelerometerY2, time_step);
  WbDeviceTag accelerometerZ2 = wb_robot_get_device("accZ2");
  wb_accelerometer_enable(accelerometerZ2, time_step);

  while (wb_robot_step(time_step) != -1) {
    //wb_motor_set_position(motor, target);
    const double *accC = wb_accelerometer_get_values(accelerometerC);    
    const double *acc1 = wb_accelerometer_get_values(accelerometer1);    
    const double *acc2 = wb_accelerometer_get_values(accelerometer2);
    const double *acc3 = wb_accelerometer_get_values(accelerometer3);

    const double *accC2 = wb_accelerometer_get_values(accelerometerC2);    
    const double *accX2 = wb_accelerometer_get_values(accelerometerX2);    
    const double *accY2 = wb_accelerometer_get_values(accelerometerY2);
    const double *accZ2 = wb_accelerometer_get_values(accelerometerZ2);

    printf("center (%f, %f, %f), (%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n",
      accC[0], accC[1], accC[2],
      acc1[0], acc1[1], acc1[2],
      acc2[0], acc2[1], acc2[2],
      acc3[0], acc3[1], acc3[2]
    );

    printf("off    (%f, %f, %f), (%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n",
      accC2[0], accC2[1], accC2[2],
      accX2[0], accX2[1], accX2[2],
      accY2[0], accY2[1], accY2[2],
      accZ2[0], accZ2[1], accZ2[2]
    );

  };
  wb_robot_cleanup();
  return 0;
}

world:

#VRML_SIM R2020a utf8
WorldInfo {
  info [
    "Example world demonstrating the use of a simple Motor device."
  ]
  title "Motor"
  basicTimeStep 4
}
Viewpoint {
  orientation 0.24623092589842271 -0.8190387028161703 -0.5182141781352672 3.8727384987635807
  position 0.24871058071651658 1.1782852200205887 -0.27399022648896354
}
TexturedBackground {
}
TexturedBackgroundLight {
}
RectangleArena {
}
DEF ROBOT Robot {
  translation -0.0004014427463162326 -0.0004414500000000064 0.000390438910127897
  rotation -2.370074307683456e-05 0.9999999990031273 3.7842042555631356e-05 -0.00019040070307766187
  children [
    HingeJoint {
      jointParameters HingeJointParameters {
        position 151.92986685785533
        axis 0 1 0
        dampingConstant 1
      }
      device [
        RotationalMotor {
          name "motor"
          consumptionFactor 100
          maxVelocity 10000
          maxTorque 100000
        }
      ]
      endPoint Solid {
        translation 7.041750370226773e-07 -9.809567583626507e-06 4.4848257919939006e-07
        rotation -5.23521314093736e-07 0.9999999999996643 6.301809531493274e-07 5.731150770827294
        children [
          Solid {
            translation 0.1 0.05 0
            children [
              Shape {
                appearance RustyMetal {
                }
                geometry Cylinder {
                  height 0.01
                  radius 0.1
                }
              }
              Accelerometer {
                translation 0 0 0.1
                name "accZ2"
              }
              Accelerometer {
                translation 0 0.1 0
                name "accY2"
              }
              Accelerometer {
                name "accC2"
              }
              Accelerometer {
                translation 0.1 0 0
                name "accX2"
              }
            ]
            boundingObject Cylinder {
              height 0.01
              radius 0.1
            }
            recognitionColors [
              0 0 0
            ]
          }
          Transform {
            translation 0.1 0 0
          }
          Accelerometer {
            name "accC"
          }
          Accelerometer {
            translation 0.1 0 0
            name "accX"
          }
          Accelerometer {
            translation 0 0.1 0
            name "accY"
          }
          Accelerometer {
            translation 0 0 0.1
            name "accZ"
          }
          DEF AXIS Group {
            children [
              Transform {
                translation 0 0.063 0
                children [
                  Shape {
                    appearance DEF METAL_APPEARANCE PBRAppearance {
                      baseColor 0.5 0.5 0.5
                      roughness 1
                      metalness 0
                    }
                    geometry Cylinder {
                      bottom FALSE
                      height 0.005
                      radius 0.04
                    }
                  }
                ]
              }
              Transform {
                translation 0 0.063 0
                children [
                  Shape {
                    appearance DEF METAL_APPEARANCE PBRAppearance {
                      baseColor 0.666667 0.666667 0.498039
                      roughness 1
                      metalness 0
                    }
                    geometry Cylinder {
                      bottom FALSE
                      height 0.008
                      radius 0.03
                      subdivision 6
                    }
                  }
                ]
              }
              Transform {
                translation 0 0.063 0.05
                rotation 1 0 0 1.5708
              }
            ]
          }
        ]
        boundingObject USE AXIS
        physics Physics {
          density -1
          mass 1
        }
        linearVelocity -3.6971584766009746e-07 6.394638193140527e-17 5.661472262531759e-07
        angularVelocity 6.512971522473201e-17 -0.7849921763042806 -4.566782209388948e-18
      }
    }
    DEF BASIS_GROUP Group {
      children [
        Transform {
          translation 0 0.02 0
          children [
            Shape {
              appearance USE METAL_APPEARANCE
              geometry Cylinder {
                bottom FALSE
                height 0.04
                radius 0.1
              }
            }
          ]
        }
        Transform {
          translation 0 0.04 0
          children [
            Shape {
              appearance PBRAppearance {
                baseColorMap ImageTexture {
                  url [
                    "textures/compass.jpg"
                  ]
                }
                roughness 1
                metalness 0
                textureTransform TextureTransform {
                  rotation 1.5708
                }
              }
              geometry Cylinder {
                bottom FALSE
                height 0.04
                radius 0.07
                side FALSE
              }
            }
          ]
        }
        Transform {
          translation 0 0.04 0
          children [
            Shape {
              appearance PBRAppearance {
                baseColor 1 0.866667 0
                roughness 1
                metalness 0
              }
              geometry Cylinder {
                bottom FALSE
                height 0.04
                radius 0.07
                top FALSE
              }
            }
          ]
        }
      ]
    }
  ]
  boundingObject USE BASIS_GROUP
  physics Physics {
    density -1
    mass 8
  }
  controller "motor"
  cpuConsumption 5
  linearVelocity -1.0403176128791755e-10 1.8474111129762606e-16 1.6914222638665206e-10
  angularVelocity 5.661198726412415e-09 -3.8533608992898905e-17 3.534036132810488e-09
}

Expected behavior accC2 should have the same reading as accX no other accelerometer reading should be the same (tangential acceleration depends from the distance from center of rotation)

What Happen the system seems to forget the accC2, accX2, accY2, accZ2 are translated, and they are all equals to accC

actual system output:

[motor] center (-0.000005, 9.810000, -0.000002), (-0.061626, 9.810000, -0.000099), (-0.000005, 9.810000, -0.000002), (0.000092, 9.810000, -0.061623)
[motor] off    (-0.000004, 9.810000, -0.000002), (-0.000004, 9.810000, -0.000002), (-0.000004, 9.810000, -0.000002), (-0.000004, 9.810000, -0.000002)
DavidMansolino commented 4 years ago

I checked your example and it seems you are indeed right, the accC2, accX2, accY2 and accZ2 accelerometers are returning non-coherent values.

omichel commented 4 years ago

It seems this is due to the fact that the parent node of accelerometers "accX2", "accY2", "accZ2" and "accC2" has no Physics node set in its physics field. Webots displays a warning about it in the console. Adding Physics node here seems to fix the problem.