webots icon indicating copy to clipboard operation
webots copied to clipboard

Constant force control reach a maximum speed

Open ShuffleWire opened this issue 3 years ago • 2 comments

Describe the Bug I'm experimenting with the inertiaMatrix and boundingBox, and found this strange behavior. In the following world, I've setup tree object (cubes), which are the same, but not placed the same way : The first one (on the left) is centered on the rotational axis. The second one (on the center) got is origin shifted by 1 meter. The third (on the right) got is origin not shifted, but it's the internal Shape node that is shifted 1 meter. Thus, in the end this object should behave exactly the same than the second one.

Those 3 cubes are powered by RotationalMotor placed on the rotation axis. Those motor apply a constant 1N.m torque.

Considering the geometry, we should expect that the left one accelerate faster that the two others.

World
#VRML_SIM R2022a utf8
WorldInfo {
  lineScale 10
}
Viewpoint {
  orientation -0.34477023131392803 0.41739621840350705 0.8407817103518561 1.5530709344074776
  position 4.053580514106406 -13.21831658643625 12.438780327125025
}
TexturedBackground {
}
TexturedBackgroundLight {
}
Robot {
  children [
    Transform {
      translation 10 0 0
      children [
        HingeJoint {
          jointParameters HingeJointParameters {
            axis 0 0 1
          }
          device [
            RotationalMotor {
              name "motor1"
            }
          ]
          endPoint Solid {
            children [
              DEF t Transform {
                translation 1 0 0
                children [
                  Shape {
                    geometry DEF c Box {
                      size 2.44949 2.44949 2.44949
                    }
                  }
                ]
              }
            ]
            name "solid(2)"
            boundingObject USE t
            physics Physics {
              density -1
              mass 1
            }
          }
        }
      ]
    }
    Transform {
      translation 5 0 0
      children [
        HingeJoint {
          jointParameters HingeJointParameters {
            axis 0 0 1
          }
          device [
            RotationalMotor {
              name "motor2"
            }
          ]
          endPoint Solid {
            translation 1 0 0
            children [
              Shape {
                geometry DEF c Box {
                  size 2.44949 2.44949 2.44949
                }
              }
            ]
            name "solid(1)"
            boundingObject USE c
            physics Physics {
              density -1
              mass 1
            }
          }
        }
      ]
    }
    Transform {
      children [
        HingeJoint {
          jointParameters HingeJointParameters {
            axis 0 0 1
          }
          device [
            RotationalMotor {
              name "motor3"
            }
          ]
          endPoint Solid {
            children [
              Shape {
                geometry DEF c Box {
                  size 2.44949 2.44949 2.44949
                }
              }
            ]
            boundingObject USE c
            physics Physics {
              density -1
              mass 1
            }
          }
        }
      ]
    }
  ]
  name "solid"
  controller "my_controller"
}
Controller
#include 
#include 

int main(int argc, char **argv) { wb_robot_init();

WbDeviceTag motor1 = wb_robot_get_device("motor1"); WbDeviceTag motor2 = wb_robot_get_device("motor2"); WbDeviceTag motor3 = wb_robot_get_device("motor3"); while (wb_robot_step(32) != -1) { wb_motor_set_torque(motor1, 1.0); wb_motor_set_torque(motor2, 1.0); wb_motor_set_torque(motor3, 1.0); }

wb_robot_cleanup();

return 0; }

Steps to Reproduce

  1. Open the world, load the controller and build it
  2. Run the world (on fast speed), during 10min
  3. Switch to normal speed
  4. Observe that center and right cube behave the same
  5. Go to the speed tab of left cube
  6. See that the speed (rotational on Z or magnitude) increase regularly (should be near 600 rad/s at that point), That's OK
  7. Same thing with center or right cube, see that the rotational speed is maxed out at 5.34071, and don't increase anymore. That's not OK
  8. At least both center and right cube behave the same, so both way of settings them don't change the result...

Expected behavior I've designed the objects in the way that center and right cube should rotate exactly at half the speed of the left one (thank to the fact that the inertia is exactly twice as high), so it should have reach at least 300 rad/s at this point. Anyway, it should not be constant...

System

  • Operating System: Debian 11
  • Webots 2022a

ShuffleWire avatar Jul 20 '22 08:07 ShuffleWire

I've made more tests, using this world :

World
#VRML_SIM R2022a utf8
WorldInfo {
  basicTimeStep 20
  lineScale 10
}
Viewpoint {
  orientation -0.34477023131392803 0.41739621840350705 0.8407817103518561 1.5530709344074776
  position 2.9014563775556645 -19.209165146189484 18.453400181273327
}
TexturedBackground {
}
TexturedBackgroundLight {
}
Robot {
  children [
    HingeJoint {
      jointParameters HingeJointParameters {
        axis 0 0 1
      }
      device [
        RotationalMotor {
          name "motor"
        }
      ]
      endPoint DEF solid Solid {
        translation 1.5 0 0
        children [
          Shape {
            geometry DEF c Box {
              size 2.44949 2.44949 2.44949
            }
          }
        ]
        name "solid(1)"
        boundingObject USE c
        physics Physics {
          density -1
          mass 1
        }
      }
    }
  ]
  name "solid"
  controller "my_controller"
  supervisor TRUE
}
Controller
#include 
#include 
#include 
#include 

int main(int argc, char **argv) { wb_robot_init();

wb_motor_set_torque(wb_robot_get_device("motor"), 1.0); WbNodeRef node = wb_supervisor_node_get_from_def("solid");

int i=1; double old_v = NAN; while (wb_robot_step(20) != -1) { const double *v = wb_supervisor_node_get_velocity(node); if(i%100 == 0) printf("%f %f\n", wb_robot_get_time(), v[5]); if(fabs(v[5] - old_v) < 1e-6) { printf("%f %f\n", wb_robot_get_time(), v[5]); break; } old_v = v[5]; i++; } wb_supervisor_simulation_reset();

wb_robot_cleanup();

return 0; }

Cube size and mass chosen to get an inertia matrix being identity.

Again, the motor apply a torque of 1 N.m

I've studied the behavior during cube rotation with different distance to the rotation axis (i.e change the x coordinate of the vector HingeJoint/endPoint/translation) (values are 0.125 , 0.2 , 0.25 , 0.4 , 0.5 , 0.75 , 1 , 1.5 , 2 , 3 , 4 , 6 , 8) We know that for no distance (ie == 0), the cube accelerate correctly, and speed increase to infinity, at exactly 1rad/s²

Take a look at the raw values in this spreadsheet (two sheets), speeds.ods but the interesting one is the following : image

I reiterate that it's not correct to see this behavior, which is not physic : all the speed should keep increasing. Moreover it's not random, as seen in the graph, it follows some rules...

ShuffleWire avatar Jul 21 '22 10:07 ShuffleWire