gazebosim / gazebo-classic

Gazebo classic. For the latest version, see https://github.com/gazebosim/gz-sim
http://classic.gazebosim.org/
Other
1.18k stars 479 forks source link

A bug in SetClipDist() in rendering::WideAngleCamera #2493

Open osrf-migration opened 6 years ago

osrf-migration commented 6 years ago

Original report (archived issue) by Huang Fan (Bitbucket: clawinshadow).


In this function, only env cameras were set with the near & clip distances, while the base camera remain the old values. Despite wide angle camera rendering images only use the 6 env cameras, I think it's still necessary to initialize the clip distances of base camera, because some other functions like isVisible() are still using the base camera. If we don't initialize the clip distances of base camera, some issue that a Visual is visible in a Camera whereas invisible in a wide angle camera with the same frustum will probably be happen(already happened in my project)

#!c++

void WideAngleCamera::SetClipDist()
{
  std::lock_guard<std::mutex> lock(this->dataPtr->dataMutex);

  // <clip> element presence is already checked
  // in Camera::SetClipDist(float,float)
  sdf::ElementPtr clipElem = this->sdf->GetElement("clip");

  for (int i = 0; i < 6; ++i)
  {
    if (this->dataPtr->envCameras[i])
    {
      this->dataPtr->envCameras[i]->setNearClipDistance(
          clipElem->Get<double>("near"));
      this->dataPtr->envCameras[i]->setFarClipDistance(
          clipElem->Get<double>("far"));
      this->dataPtr->envCameras[i]->setRenderingDistance(
          clipElem->Get<double>("far"));
    }
    else
    {
      gzerr << "Setting clip distances failed - no camera yet" << std::endl;

      break;
    }
  }
}
osrf-migration commented 6 years ago

Original comment by Huang Fan (Bitbucket: clawinshadow).


osrf-migration commented 6 years ago

Original comment by Ian Chen (Bitbucket: Ian Chen, GitHub: iche033).


as a workaround, I think you can use the WideAngleCamera::Project3d function to check visibility. If the z component of the returned vector is anywhere outside of [0, 1] then the object is not visible.

osrf-migration commented 6 years ago

Original comment by Huang Fan (Bitbucket: clawinshadow).


Hi, Ian, thank you for your reply, but this function accept a Vector param (ignition::math::Vector3d), while I got a Visual to pass. How can I convert a Visual to Vector3d?

osrf-migration commented 6 years ago

Original comment by Ian Chen (Bitbucket: Ian Chen, GitHub: iche033).


you can use the visual position in the world for checking it's visibility, e.g. for gazebo9 it would be: visual->WorldPose().Pos()

osrf-migration commented 6 years ago

Original comment by Huang Fan (Bitbucket: clawinshadow).


Hi, Ian. I think this position is a kind of "center" position of the object(either geometric center or gravity center), if I use the projection of this center position vector to check visibility, another exception would raise that a corner(or part) of the object is actually visible in the frustum of camera, in spite of the center is out of it, we can't ensure the consistency of the visibility of all the corners & center.

Currently I use the pointer of Ogre::Camera to set the near & far clip distances to make it work normally, some pseudocode as below:

#!c++

Ogre::Camera* o_camera = wide_angle_camera_ptr->OgreCamera();

o_camera->setNearClipDistance(near_clip_dist);
o_camera->setFarClipDistance(far_clip_dist);

what's your concern? thank you.

osrf-migration commented 6 years ago

Original comment by Ian Chen (Bitbucket: Ian Chen, GitHub: iche033).


the concern is that there could be inconsistency between the base camera frustum and a wide angle camera frustum with the same FOV. This page gives a nice illustration. The difference becomes more apparent at large FOVs.

osrf-migration commented 6 years ago

Original comment by Huang Fan (Bitbucket: clawinshadow).


Hi, Ian. I read this page, I agree it's better to use projection of

#!c++

visual->WorldPose().Pos()

but as I said in last comment, how to eliminate the inconsistency between the visibility of center and all the corners? thank you.

osrf-migration commented 6 years ago

Original comment by Ian Chen (Bitbucket: Ian Chen, GitHub: iche033).


you could project and check all corners. That'll be more accurate but a little expensive

osrf-migration commented 6 years ago

Original comment by Huang Fan (Bitbucket: clawinshadow).


Thank you Ian, currently I will check all corners to get the correct visibility, but for long term I expect gazebo dev team would override the IsVisible() function in WideAngleCamera class, to be a natural & official solution.

osrf-migration commented 6 years ago

Original comment by Huang Fan (Bitbucket: clawinshadow).


Hi, Ian. I find that rendering::Scene::VisualAt() not work for WideAngleCamera, maybe we need to use the env cameras for the _camera parameter, is there any workaround? thank you

osrf-migration commented 6 years ago

Original comment by Ian Chen (Bitbucket: Ian Chen, GitHub: iche033).


ya VisualAt currently doesn't support wide angle cameras. This will be quite tricky to implement or find a workaround. We will need to first solve the problem of identifying which env camera sees the input mouse point and the corresponding image location in that env camera before passing them to Scene::VisualAt. It's kind of an inverse problem which the Project3d function is solving. Unfortunately, I cannot think of a quick workaround for now.