http://openig.compro.net
https://www.compro.net/openig_forum/

Set position, head, pitch, and roll angles in OpenIG
https://www.compro.net/openig_forum/viewtopic.php?f=10&t=93
Page 2 of 2

Author:  trajce.nikolov.nick [ Fri Aug 21, 2015 9:40 am ]
Post subject:  Re: Set position, head, pitch, and roll angles in OpenIG

Hi again Mr. Baggio,

finally I spent some time on this, and yes, I can confirm your original findings where roll acts as yaw - If I am not mistaken. This really seams to look as an OSG bug/issue, so I started on the osg user forum a thread for it, and hopefully it will get resolved.

Also, just for the sake of completeness of this thread here, instead of the first shot of Quaternion math I figured out it can be done in OSG in much simplier way. Here is some code for using geodetic coordinates and euler (NED alike) orientations for placing a camera on an ellipsoid - again, just to wrap up this thread, I am aware your visual database is not geocentric

Code:
osg::Matrixd toMatrix(double x, double y, double z, double h, double p, double r)
{
   osg::Matrixd mxR;
   mxR.makeRotate(osg::DegreesToRadians(r), osg::Vec3(0, 1, 0));
   osg::Matrixd mxP;
   mxP.makeRotate(osg::DegreesToRadians(p), osg::Vec3(1, 0, 0));
   osg::Matrixd mxH;
   mxH.makeRotate(osg::DegreesToRadians(-h), osg::Vec3(0, 0, 1));
   osg::Matrixd mxT;
   mxT.makeTranslate(osg::Vec3(x, y, z));

   return (mxR*mxP*mxH*mxT);
}

      double lat = 36.9268;
      double lon = -75.9845;
      double alt = 5608.62;
            
      static double heading = 0.0;
      static double pitch = 0.0;
      static double roll = 0.0;

      osg::Vec3d euler(heading, pitch+osg::DegreesToRadians(90.0), roll);      

      roll += osg::DegreesToRadians(1.0);      

      osg::Matrixd mx = toMatrix(
         0.0,0.0,0.0,
         osg::RadiansToDegrees(euler.x()), osg::RadiansToDegrees(euler.y()), osg::RadiansToDegrees(euler.z())
      );

      osg::EllipsoidModel em;
      osg::Matrixd l2w;
      em.computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(lat), osg::DegreesToRadians(lon), alt, l2w);

      viewer->getView(0)->getCamera()->setViewMatrix(osg::Matrixd::inverse(mx * l2w));

Author:  baggiodlb [ Mon Aug 24, 2015 9:46 am ]
Post subject:  Re: Set position, head, pitch, and roll angles in OpenIG

Hi, Nick. Thank you for your comments.

Thanks to your help, we got that fixed.

I was struggling with rotation order and initial camera position.
It seems that initially, according to the image below, we got the camera pointing down (-Z), and the up vector aligned to Y.

So, we have defined these axis:
Code:
   osg::Vec3 yawAxis( 0.f, 0.f, 1.f );
   osg::Vec3 pitchAxis( 1.f, 0.f, 0.f );
   osg::Vec3 rollAxis( 0.f, 1.f, 0.f );

And then, these rotations were made:
1st: Bring camera pointing to roll axis:
Code:
osg::Matrixd pointAhead;
   pointAhead.makeRotate(osg::DegreesToRadians(90.0),pitchAxis);

2nd: Point camera to pitch axis:
Code:
osg::Matrixd pointRight;
   pointRight.makeRotate(osg::DegreesToRadians(-90.0),yawAxis);

Now, we have the camera pointing to +X and the up vector is +Z.

It is time to apply heading pitch and roll.
3rd: apply roll first (we are going to rotate around pitch axis, since this is actually our roll direction, notice the r parameter):
Code:
   osg::Matrixd pitchMatrix;
   pitchMatrix.makeRotate(osg::DegreesToRadians(r), pitchAxis);


4th: apply our pitch (we are going to rotate around our rollAxis, since this is actually the pitch we expect, notice the p parameter):
Code:
   osg::Matrixd rollMatrix;
   rollMatrix.makeRotate(osg::DegreesToRadians(-p), rollAxis);

5th: eventually, we will apply our heading, according to our Z axis:

Code:
   osg::Matrixd yawMatrix;
   yawMatrix.makeRotate(osg::DegreesToRadians(-h+90), yawAxis);


Now we create the rotation matrix (notice that left multiplications occur first):

Code:
cameraRotation = pointAhead * pointRight * pitchMatrix * rollMatrix  * yawMatrix  ;


Complete code goes here:

Code:
osg::Matrixd createMatrixExt(double x, double y, double z, double h, double p, double r)
{
   
    osg::Matrixd myCameraMatrix;

     osg::Matrixd cameraRotation;
     osg::Matrixd cameraTrans;




   osg::Vec3 yawAxis( 0.f, 0.f, 1.f );
   osg::Vec3 pitchAxis( 1.f, 0.f, 0.f );
   osg::Vec3 rollAxis( 0.f, 1.f, 0.f );

   cameraRotation.makeIdentity();
   osg::Matrixd pointAhead;
   pointAhead.makeRotate(osg::DegreesToRadians(90.0),pitchAxis);

   osg::Matrixd pointRight;
   pointRight.makeRotate(osg::DegreesToRadians(-90.0),yawAxis);

   osg::Matrixd yawMatrix;
   yawMatrix.makeRotate(osg::DegreesToRadians(-h+90), yawAxis);
   osg::Matrixd pitchMatrix;
   pitchMatrix.makeRotate(osg::DegreesToRadians(r), pitchAxis);
   osg::Matrixd rollMatrix;
   rollMatrix.makeRotate(osg::DegreesToRadians(-p), rollAxis);
   
   cameraRotation = pointAhead * pointRight * pitchMatrix * rollMatrix  * yawMatrix  ;
      
   cameraTrans.makeTranslate( osg::Vec3(x,y,z) );
   myCameraMatrix = cameraRotation * cameraTrans;

   return myCameraMatrix;
}


And we use it like this:

Code:
osg::Matrix xyzhprMat = createMatrixExt( longitudeDegrees, latitudeDegrees, altitudeMeters, headingDegrees, pitchDegrees, rollDegrees);
      view->getCamera()->setViewMatrix( osg::Matrixd::inverse(xyzhprMat) );


Image

Big thanks!

Author:  kabeck [ Mon Aug 24, 2015 12:11 pm ]
Post subject:  Re: Set position, head, pitch, and roll angles in OpenIG

Thank You Mr. Baggio.

Nice work !!! You are hired !!


Keith

Author:  baggiodlb [ Mon Aug 24, 2015 12:49 pm ]
Post subject:  Re: Set position, head, pitch, and roll angles in OpenIG

hehehe...

Unfortunately, it took me a couple weeks. Maybe I can hide that info from my curriculum. :roll:

Still, we got another silly problem. I'll post it in another thread and see if you can help me. :P

Author:  trajce.nikolov.nick [ Thu Jun 23, 2016 8:50 am ]
Post subject:  Re: Set position, head, pitch, and roll angles in OpenIG

Hi All,

back to the issue for this thread which become actual again while testing the upcoming CIGI plugin and work with osgEarth in ECEF geocentric. The following code makes it even more simplified ... here is the code from the CIGI plugin which updates the camera based on Lat/Lon/Alt in degrees and Heading/Pitch/Roll in Euler
Code:

EntityState& es = itr->second;

osg::Matrixd l2w;

osg::EllipsoidModel em;
em.computeLocalToWorldTransformFromLatLongHeight(
                        osg::DegreesToRadians(es.lat),
                        osg::DegreesToRadians(es.lon),
                        es.alt,
                        l2w
                    );

osg::Matrixd mx =
                            osg::Matrixd::rotate(OpenIG::Base::Math::instance()->toQuat(0,90,0)) *
                            osg::Matrixd::rotate(OpenIG::Base::Math::instance()->toQuat(es.h, es.p, es.r)) * l2w;

context.getImageGenerator()->setCameraPosition(mx);


Page 2 of 2 All times are UTC - 5 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/