OSG/OSGEarth How to move a Camera

1.3k Views Asked by At

I'm making a Drone simulator with OSGEarth. I never used OSG before so I have some troubles to understand cameras. I'm trying to move a Camera to a specific location (lat/lon) with a specific roll, pitch and yaw in OSG Earth.

I need to have multiple cameras, so I use a composite viewer. But I don't understand how to move the particular camera. Currently I have one with the EarthManipulator which works fine.

 class NovaManipulator : publicosgGA::CameraManipulator {
         osg::Matrixd NovaManipulator::getMatrix() const
            {
              //drone_ is only a struct which contains updated infomations
              float roll = drone_->roll(),
              pitch = drone_->pitch(),
              yaw = drone_->yaw();

          auto position = drone_->position();
          osg::Vec3d world_position;
          position.toWorld(world_position);

          cam_view_->setPosition(world_position);

          const osg::Vec3d rollAxis(0.0, 1.0, 0.0);
          const osg::Vec3d pitchAxis(1.0, 0.0, 0.0);
          const osg::Vec3d yawAxis(0.0, 0.0, 1.0);

           //if found this code : 
           // https://stackoverflow.com/questions/32595198/controling-openscenegraph-camera-with-cartesian-coordinates-and-euler-angles
           osg::Quat rotationQuat;
           rotationQuat.makeRotate(
               osg::DegreesToRadians(pitch + 90), pitchAxis,
               osg::DegreesToRadians(roll),          rollAxis,
               osg::DegreesToRadians(yaw),          yawAxis);

          cam_view_->setAttitude(rotationQuat);

          // I don't really understand this also
          auto nodePathList = cam_view_->getParentalNodePaths();
          return osg::computeLocalToWorld(nodePathList[0]);
        }

        osg::Matrixd NovaManipulator::getInverseMatrix() const
        {
          //Don't know why need to be inverted
          return osg::Matrix::inverse(getMatrix());
        } 
    };

Then I install the manupulator to a Viewer. And when I simulate the world, The camera is on the good place (Lat/Lon/Height). But the orientation in completely wrong and I cannot find where I need to "correct" the axis.

Actually my drone is in France but the "up" vector is bad, it still head to North instead of "vertical" relatively to the ground. See what I'm getting on the right camera

I need to have a yaw relative to North (0 ==> North), and when my roll and pitch are set to zero I need to be "parallel" to the ground.

Is my approach (by making a Manipulator) is the best to do that ? Can I put the camera object inside the Graph node (behind a osgEarth::GeoTransform (it works for my model)) ?

Thanks :)

2

There are 2 best solutions below

0
On BEST ANSWER

In the past, I have done a cute trick involving using an ObjectLocator object (to get the world position and plane-tangent-to-surface orientation), combined with a matrix to apply the HPR. There's an invert in there to make it into a camera orientation matrix rather than an object placement matrix, but it works out ok.

http://forum.osgearth.org/void-ObjectLocator-setOrientation-default-orientation-td7496768.html#a7496844

It's a little tricky to see what's going on in your code snippet as the types of many of the variables aren't obvious.

AlphaPixel does lots of telemetry / osgEarth type stuff, so shout if you need help.

0
On

It is probably just the order of your rotations - matrix and quaternion multiplications are order dependent. I would suggest:

  1. Try swapping order of pitch and roll in your MakeRotate call.
  2. If that doesn't work, set all but 1 rotation to 0° at a time, making sure each is what you expect, then you can play with the orders (there are only 6 possible orders).
  3. You could also make individual quaternions q1, q2, q3, where each represents h,p, and r, individually, and multiply them yourself to control the order. This is what the overload of MakeRotate you're using does under the hood.

Normally you want to do your yaw first, then your pitch, then your roll (or skip roll altogether if you like), but I don't recall off-hand whether osg::quat concatenates in a pre-mult or post-mult fashion, so it could be p-r-y order.