ros-controls / ros_control

Generic and simple controls framework for ROS
http://wiki.ros.org/ros_control
BSD 3-Clause "New" or "Revised" License
469 stars 307 forks source link

joint_limits_interface.h Error #490

Closed erdisayar closed 3 years ago

erdisayar commented 3 years ago

Hi System Ubuntu 18, ROS Melodic

When I try to use the following camera in the sdf file, I am getting the joint_limits_interface.h error

gzserver: /opt/ros/melodic/include/joint_limits_interface/joint_limits_interface.h:190: void joint_limits_interface::PositionJointSoftLimitsHandle::enforceLimits(const ros::Duration&): Assertion `period.toSec() > 0.0' failed.

Here is the camera codes

<model name="camera">
  <pose>1 1 1 -1.5707 1.5707 0</pose>
  <static>1</static>
  <link name='camera_link'>
   <pose frame=''>0 0 0 0 0 0</pose>
  <inertial>
    <mass>0.1</mass>
    <inertia>
      <ixx>1</ixx>
      <ixy>0</ixy>
      <ixz>0</ixz>
      <iyy>1</iyy>
      <iyz>0</iyz>
      <izz>1</izz>
    </inertia>
    <pose frame=''>0 0 0 0 -0 0</pose>
  </inertial>
  <self_collide>0</self_collide>
  <kinematic>0</kinematic>
  <sensor name='camera1' type='camera'>
    <camera name="head">
      <horizontal_fov>1.3962634</horizontal_fov>
      <image>
        <width>800</width>
        <height>800</height>
        <format>R8G8B8</format>
      </image>
      <clip>
        <near>0.02</near>
        <far>300</far>
      </clip>
    </camera>
    <always_on>1</always_on>
    <update_rate>30</update_rate>
    <visualize>1</visualize>
    <plugin name="camera_controller" filename="libgazebo_ros_camera.so">
    <alwaysOn>true</alwaysOn>
    <updateRate>0.0</updateRate>
    <cameraName>shadow_hand/camera</cameraName>
    <imageTopicName>image_raw</imageTopicName>
    <cameraInfoTopicName>camera_info</cameraInfoTopicName>
    <frameName>camera_link</frameName>
    <hackBaseline>0.07</hackBaseline>
    <distortionK1>0.0</distortionK1>
    <distortionK2>0.0</distortionK2>
    <distortionK3>0.0</distortionK3>
    <distortionT1>0.0</distortionT1>
    <distortionT2>0.0</distortionT2>
  </plugin>
  </sensor>
  </link>
  </model

How does a camera link use the joint limit interface ?

matthew-reynolds commented 3 years ago

This question probably belongs at https://github.com/ros-simulation/gazebo_ros_pkgs or on http://answers.ros.org. I can try to point you in the right direction though:

How does a camera link use the joint limit interface?

It doesn't. But if you're using the default gazebo_ros_control Gazebo plugin, then joint limits are registered and enforced for every joint handle in the system. (See https://github.com/ros-simulation/gazebo_ros_pkgs/blob/98bb3d0a0afc65725deaa1633e21ff6f5322b564/gazebo_ros_control/src/default_robot_hw_sim.cpp). So maybe you've got some joints defined elsewhere in your URDF or something. Hard to know without more information.

I am getting the joint_limits_interface.h error [...] Assertion 'period.toSec() > 0.0' failed

This is telling you directly your issue. The control period must be positive. The ros_control framework does not support negative control periods since they're sorta nonsensical. You should figure out where you're calling ControllerManager::update() and ensure the period being passed in is always positive (ie based on a strictly monotonically increasing time source). If you're using the gazebo_ros_control plugin, then it gets its period from Gazebo which I imagine should be strictly monotonic, but maybe there are edge cases where it's not, I don't know.

I don't have a lot of answers for you, but hopefully that points you in the right direction to investigate further. I'm going to close this issue since the problem is not with ros_control but rather with either your setup or one of the plugins you're using.

erdisayar commented 3 years ago

Thanks, Matthew, I understood the origin of my problem and maybe I can consult you about it. When the Gazebo is loaded and started in pause mode, then I am doing the followings in Gazebo Plugin Load function if (world->IsPaused()) { world->Step(1); world_->ResetTime(); } Firstly, I advanced the simulation time by one iteration. So I can make sure that my plugins are loaded. Then I am calling ResetTime() function to reset time in Gazebo. In this step, line 190 joint_limits_interface.h arises an error. Because my period.toSec() is exactly 0 ( not greater than 0) image

I think anyone might want to reset its gazebo time anytime and this error might affect others as well. Do you think it can be a bug in joint_limits_interface.h ?

From previous message, I understand that controller time must be positive but Why can't it be 0 ?

Thanks

matthew-reynolds commented 3 years ago

Guess there is an edge case in Gazebo that yields non-monotonic time - Resetting time! Makes sense.

I've never had to use ResetTime() in my Gazebo plugins. Not sure if your case is more complex than mine or if you're doing something funky, but it's worth verifying that you truly need to reset the time. If you really need to, an easy workaround is to just skip calling the ControllerManager::Update() when time=0 or period=0. A hack around ControllerManager::Update() to match the hacky call to ResetTime() 😄

Supporting a period of 0 in ros_control would probably mean introducing a special cases to handle division by 0 and the behaviour would be kinda weird anyways since it basically just means repeat previous command. It's probably feasible, but since we've gotten by fine without it for coming up on 10 years, I'm inclined to leave things as they are.