Displaying the Earth's Rotation

1,183 views
Skip to first unread message

Eric Miller

unread,
Jul 12, 2012, 12:49:12 PM7/12/12
to cesiu...@googlegroups.com

Is there a way to display the earth's inertial rotation, the way Insight3D does by default?  I'm not sure if this is a function of central body, camera, scene, etc, but I've been looking for a way to set this and haven't found one.

Patrick Cozzi

unread,
Jul 12, 2012, 5:03:10 PM7/12/12
to cesiu...@googlegroups.com
Hi Eric,

We don't have this right now; however, below you will find an approximation for converting from TEME to pseudo-fixed.  You can use it to set the camera's transform, and make the globe spin.  In the skeleton, replace the scene.setAnimation(...) call with this:

    /**
     * Computes a rotation matrix to transform a point or vector from True Equator Mean Equinox (TEME) axes to the
     * pseudo-fixed axes at a given time.  This method treats the UT1 time standard as equivalent to UTC.
     *
     * @param {Cesium.JulianDate} date The time in either TAI or UTC at which to compute the rotation matrix.
     *
     * @return {Cesium.Matrix3} A rotation matrix that transforms a vector in the TEME axes to the pseudo-fixed axes at the given {@code date}.
     */
    function computeTemeToPseudoFixedMatrix (date) {
        // GMST is actually computed using UT1.  We're using UTC as an approximation of UT1.

        var gmstConstant0 = 6 * 3600 + 41 * 60 + 50.54841;
        var gmstConstant1 = 8640184.812866;
        var gmstConstant2 = 0.093104;
        var gmstConstant3 = -6.2E-6;
        var rateCoef = 1.1772758384668e-19;
        var wgs84WRPrecessing = 7.2921158553E-5;
        var dateInUtc = date.addSeconds(-date.getTaiMinusUtc());

        var t;
        var diffDays = dateInUtc.getJulianDayNumber() - 2451545;
        if (dateInUtc.getSecondsOfDay() >= 43200.0) {
            t = (diffDays + 0.5) / Cesium.TimeConstants.DAYS_PER_JULIAN_CENTURY;
        } else {
            t = (diffDays - 0.5) / Cesium.TimeConstants.DAYS_PER_JULIAN_CENTURY;
        }

        var gmst0 = gmstConstant0 + t * (gmstConstant1 + t * (gmstConstant2 + t * gmstConstant3));
        var angle = (gmst0 * Cesium.Math.TWO_PI / 86400.0) % Cesium.Math.TWO_PI;
        var ratio = wgs84WRPrecessing + rateCoef * (dateInUtc.getJulianDayNumber() - 0.5 - 2451545);

        var secondsSinceMidnight = (dateInUtc.getSecondsOfDay() + Cesium.TimeConstants.SECONDS_PER_DAY / 2.0) % 86400.0;

        var gha = angle + (ratio * secondsSinceMidnight);

        var cosGha = Math.cos(gha);
        var sinGha = Math.sin(gha);
        return new Cesium.Matrix3(cosGha, sinGha, 0.0, -sinGha, cosGha, 0.0, 0.0, 0.0, 1.0);
    }

    var time = new Cesium.JulianDate();

    scene.setAnimation(function() {
        scene.setSunPosition(Cesium.SunPosition.compute(time).position);
        time = time.addSeconds(20.0);

        scene.getCamera().transform = new Cesium.Matrix4(computeTemeToPseudoFixedMatrix(time), Cesium.Cartesian3.ZERO);
    });

When the globe is spinning, camera control gets a bit hairy.  I opened issue #105 to look into this.

Regards,
Patrick


On Thu, Jul 12, 2012 at 12:49 PM, Eric Miller <emac...@gmail.com> wrote:

Is there a way to display the earth's inertial rotation, the way Insight3D does by default?  I'm not sure if this is a function of central body, camera, scene, etc, but I've been looking for a way to set this and haven't found one.

--
You received this message because you are subscribed to the Google Groups "cesium-dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cesium-dev/-/Kn5EG1rULqUJ.
To post to this group, send email to cesiu...@googlegroups.com.
To unsubscribe from this group, send email to cesium-dev+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cesium-dev?hl=en.



--
www.seas.upenn.edu/~pcozzi/

Eric Miller

unread,
Jul 13, 2012, 12:20:16 PM7/13/12
to cesiu...@googlegroups.com
Patrick,
Thanks for that code.  I was able to get that working in the CesiumViewer, and I see what you mean about the camera controls.

Will I need to provide all of my positional data in ECEF?  My propagation algorithms currently deal only in ECI and my ECEF conversion code is buried in FORTRAN in a place I can't get to it, so I will need to do some work to convert.  I know this is easy to do in STK Components, and I was just curious what the plan for this is.

Eric

Patrick Cozzi

unread,
Jul 13, 2012, 1:58:44 PM7/13/12
to cesiu...@googlegroups.com
Eric,

Currently, there are not plans for ECI to ECEF in Cesium.  However, you could use the function I provided to set the primitive's model transform as an approximation, e.g.

polyline.model = computeTemeToPseudoFixedMatrix(time);
polyline.setPositions(/* positions in ECI, well, really TEME */);

Regards,
Patrick



Eric

--
You received this message because you are subscribed to the Google Groups "cesium-dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cesium-dev/-/2u7qAYQIN-QJ.

To post to this group, send email to cesiu...@googlegroups.com.
To unsubscribe from this group, send email to cesium-dev+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cesium-dev?hl=en.

Daniel Oneil

unread,
Mar 9, 2016, 2:19:14 PM3/9/16
to cesium-dev
I have not been able to get this code to work in Sandcastle.

Here are the error messages:
  • TypeError: viewer.scene.setAnimation is not a function (on line 45)
  • TypeError: Cesium.SunPosition is undefined (on line 46)
  • TypeError: time.addSeconds is not a function (on line 49)
Have there been API changes that affects this code?
Is this code still the way to get the Earth to rotate?

Daniel Oneil

unread,
Mar 10, 2016, 9:11:13 AM3/10/16
to cesium-dev

The time interval for this space mission visualization is 2014-07-22 T11:00:00Z to 2014-08-12 T22:07:27Z.
Buttons on the left side of the page enable selection of viewpoints one of the viewpoints is the Earth.
http://daoneil.github.io/spacemission/Apps/EarthToMoon_withNav.html

An ideal implementation would be to tie the rotation of the Earth to the time widget shuttle ring.
What code would enable time widget driven Earth rotation?

Hannah Pinkos

unread,
Mar 10, 2016, 10:31:34 AM3/10/16
to cesium-dev
Hello,

This code sample is very old, and the API has changed since then.

From the menu, select 'View in ICRF' and look at that section of the code.

Best,

Hannah

Daniel Oneil

unread,
Mar 14, 2016, 4:01:50 PM3/14/16
to cesium-dev

I implemented the code from the camera Sandcastle demo. Now, the problem is the trajectories rotate along with the Earth.
This link leads to the version with the camera.transform. Please wait 30 seconds until the buttons are no longer grey then click on the Earth button.
http://daoneil.github.io/spacemission/Apps/EarthToMoon_spinGlobe.html

I'm wondering whether it's possible to periodically update the orientation of the viewer.scene.globe.ellipsoid.
I've tried setting the orientation to a Matrix4 and Quaternion and I get type errors.
What is the data type of an entity's orientation?

Here is some code that I have attempted in Sandcastle:

var viewer = new Cesium.Viewer('cesiumContainer');

var currentAngle = 0 ;
// var m = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(currentAngle));

var zAxis = new Cesium.Cartesian3(0, 0, 1) ;
var rotquat = new Cesium.Quaternion.fromAxisAngle(zAxis,Cesium.Math.toRadians(currentAngle)) ;

viewer.clock.onTick.addEventListener(function(clock) {         

 //  viewer.scene.globe.ellipsoid.orientation = Cesium.Matrix4.fromRotationTranslation(m, Cesium.Cartesian3.ZERO);
 
    console.log("ready to set orientation") ;
    viewer.scene.globe.ellipsoid.orientation = rotquat ;
   
    currentAngle = currentAngle + 1 ;
    if (currentAngle > 360) { currentAngle = 0 ; }
   
    rotquat = Cesium.Quaternion.fromAxisAngle(zAxis,Cesium.Math.toRadians(currentAngle)) ;
   
 //  m = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(currentAngle)) ;
                       
});

Hannah Pinkos

unread,
Mar 14, 2016, 6:07:58 PM3/14/16
to cesium-dev
Cool demo!
I see, your coordinates are already in ICRF.  That's why they're moving.
In your CZML file, you can define the reference frame for your positions.
Try

"position": {  
       
"referenceFrame": "INERTIAL",
.....

Hope this helps!

-Hannah

Daniel Oneil

unread,
Mar 16, 2016, 3:28:01 PM3/16/16
to cesium-dev
Hannah -

Thanks! adding the inertial reference frame to the CZML files fixed the problem with the trajectories rotating with the Earth.
Now, the view point buttons no longer work, probably because the camera and the tracked entity are in two different reference frames.

This code snippet is the function called by the view point Moon button:

function showTheMoon() {
    var ourMoon = czmlDataSource2.entities.getById('theMoon') ;   
    viewer.trackedEntity = ourMoon ; 
}

In the function called by the Spacecraft button, I attempted to produce a transform based on the lunar probe's position and use the transform in the camera.looAtTtransform function.

function showSpaceCraft() {
   var spaceCraft = czmlDataSource1.entities.getById('lunarProbe') ;

   var center = spaceCraft.position.getValue(Cesium.JulianDate.now()) ;
       center.x = center.x + 10 ;
       center.y = center.y + 10 ;  // move center away from the spacecraft
     
      console.log ("center ", center) ;                  // nothing appears in the console
      
// Get the transform from local east-north-up at the adjusted center.
   var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);

   viewer.camera.lookAtTransform(transform, spaceCraft.position.getValue(Cesium.JulianDate.now()));

}

The current model -- http://daoneil.github.io/spacemission/Apps/EarthToMoon_spinGlobe.html

Thanks for your guidance.

Hannah Pinkos

unread,
Mar 17, 2016, 10:41:58 AM3/17/16
to cesium-dev
It looks like there's a typo in your example that's throwing an error to the console.  I'm not sure if that's the root of your problem though.

spaceCraft is an entity, correct?  To track it, you could set viewer.trackedEntity = spaceCraft; (and viewer.trackedEntity = undefined; to untrack it)

Best,

Hannah

Daniel Oneil

unread,
Mar 18, 2016, 3:17:49 PM3/18/16
to cesium-dev

Hannah -

Thanks for mentioning the typo; interestingly, the web console in FireFox did not catch it but the web console in Chrome did.

Please look at these two versions of the same demo.
Within the function called by the spacecraft button is  viewer.trackedEntity = spaceCraft ; and
within the function called by the moon button is viewer.trackedEntity = ourMoon ;

These functions work as desired in the EarthToMoon_withCam but they don't work in EarthToMoon_ICRF.
In the _ICRF version, pressing the spacecraft or moon buttons only show an empty star-field.

Both demo versions include the following code:

    function icrf(scene, time) {
    if (scene.mode !== Cesium.SceneMode.SCENE3D) {
        return;
    }

    var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);
    if (Cesium.defined(icrfToFixed)) {
        var camera = viewer.camera;
        var offset = Cesium.Cartesian3.clone(camera.position);
        var transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
        camera.lookAtTransform(transform, offset);
    }
}
     clock.multiplier = 3 * 60 * 60;
    scene.preRender.addEventListener(icrf); 

The only difference the is last line, which adds the event listener -- it is commented out in the _withCam version.
Adding the event listener does cause the Earth to spin while keeping the trajectories still.

Per your previous suggestion, the CZML files include:
"position": {  
       
"referenceFrame": "INERTIAL",

With the camera in ICRF and the trajectories in an Inertial reference frame, wouldn't we need to
transform coordinates so the camera and the models are in the same reference frame?

Thanks.

Hannah Pinkos

unread,
Mar 21, 2016, 10:49:23 AM3/21/16
to cesium-dev
Hello,

Just to make sure I understand, for the EarthToMoon_ICRF demo, you are using referenceFrame: INERTIAL in the CZML and the scene.preRender event?

-Hannah

Daniel Oneil

unread,
Mar 21, 2016, 2:12:57 PM3/21/16
to cesium-dev
In the EarthToMoon_ICRF demo, I have the INERTIAL reference frame specified in the CZML code that specifies the lunar probe and the Moon's orbit.
The scene.preRender event is in the JavaScript; here is the script:

<script>
   var viewer = new Cesium.Viewer('cesiumContainer', {
       infoBox : false,
       selectionIndicator : false
    });
    var scene = viewer.scene;
    var clock = viewer.clock;

   var czmlDataSource1 = new Cesium.CzmlDataSource();
       czmlDataSource1.load('LunarProbeTrajectory_withBillboard.czml');      // Load the CZML for the lunar probe
       viewer.dataSources.add(czmlDataSource1);
      
   var czmlDataSource2 = new Cesium.CzmlDataSource();
       czmlDataSource2.load('LunarOrbit_andBillboard.czml');                     // Load the CZML for the Moon's trajectory
       viewer.dataSources.add(czmlDataSource2);  

          function icrf(scene, time) {
    if (scene.mode !== Cesium.SceneMode.SCENE3D) {
        return;
    }

    var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);
    if (Cesium.defined(icrfToFixed)) {
        var camera = viewer.camera;
        var offset = Cesium.Cartesian3.clone(camera.position);
        var transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
        camera.lookAtTransform(transform, offset);
    }
}
     clock.multiplier = 3 * 60 * 60;
    scene.preRender.addEventListener(icrf);         // <-- In the EarthToMoon_withCam demo, this line is commented out.
    scene.globe.enableLighting = true;
     
       viewer.scene.camera.frustum.far = 1e12;            //Move the far wall of the viewing frustum.
   
    // Set position for the big picture view
      viewer.camera.setView({
      destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.0, 1500000000.0)
     });

</script>

In the EarthToMoon_withCam version, you can see the spacecraft or the Moon when you click the buttons; however the trajectories spin with the Earth.
In the EarthToMoon_ICRF version, the Earth spins, the trajectories stay put but you no longer see the spacecraft or the Moon when you click the buttons.

Should the CZML files have something in them about the scene.preRender event or the ICRF?

Thanks,

- Dan
Message has been deleted

Daniel Oneil

unread,
Mar 24, 2016, 4:48:46 PM3/24/16
to cesium-dev
Some success!
This version works, albeit sporadically, http://daoneil.github.io/spacemission/Apps/EarthToMoon_Transforms.html

Now, the Earth spins, the trajectories, stay still, and the buttons work the first time. On subsequent clicks of the Spacecraft button there is only night-sky; however, if you press the Moon button before pressing the Spacecraft button then the Spacecraft appears.
The code for the main script as presented in my previous post.
Here are the functions that are called by the buttons:

function bigPicture() {
      viewer.trackedEntity = undefined
      scene.preRender.
addEventListener(icrf);

      viewer.camera.setView({
      destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.0, 1500000000.0)
     });
     viewer.trackedEntity = earthCore ;
     console.log ("big picture") ;
}

function showSpaceCraft() {
    viewer.trackedEntity = undefined
    scene.preRender.removeEventListener(icrf);


    var spaceCraft = czmlDataSource1.entities.getById('lunarProbe') ;   
      viewer.trackedEntity = spaceCraft ;
}
function showTheMoon() {
    viewer.trackedEntity = undefined
    scene.preRender.removeEventListener(icrf);


    var ourMoon = czmlDataSource2.entities.getById('theMoon') ;   
    viewer.trackedEntity = ourMoon ;
}
function showTheEarth() {
      viewer.trackedEntity = undefined 
      scene.preRender.addEventListener(icrf);
  // Set position with a top-down view
      viewer.camera.setView({
      destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.0, 150000000.0)
     });
      viewer.trackedEntity = earthCore ;
}

What has changed? The functions called by the Spacecraft and Moon buttons removes the event listener that was added in the main script.
The buttons for the big picture and the Earth add the event listener for ICRF. If someone could let me know how to make the program a little more robust regarding the spacecraft as a tracked entity, I would appreciate it.


Hannah Pinkos

unread,
Mar 24, 2016, 6:21:25 PM3/24/16
to cesium-dev
Sorry I never got back to you.  Glad you were able to figure out a solution!
What is the problem you were seeing now?  I wasn't able to reproduce it.  I clicked the spacecraft button multiple times and switched back and forth between the spacecraft and moon views and everything seemed to work fine.

By the way, we do add a moon ellipsoid to the scene (which I'm sure you've noticed).  You can turn off our moon by doing viewer.scene.moon.show = false; 
And you can add our texture to your moon with 

    "ellipsoid" : {
     
"radii" : {
       
"cartesian" : [...]
     
},
     
"material" : {
       
"image" : {
         
"image" : { "uri" : "path/to/Cesium/Source/Assets/Textures/moonSmall.jpg" }
       
}
     
}
   
}


I'm not sure which version of Cesium you're using, but the hole in the top of the moon should have be fixed if you use the latest version, 1.19

Best,

Hannah

Daniel Oneil

unread,
Mar 25, 2016, 4:05:02 PM3/25/16
to cesium-dev
Hannah -

Thanks for the suggested alternative approaches, I chose to turn off the default Moon and texture map an ellipsoid.
I added a Boolean flag to check before adding or removing the ICRF event listener.
The CZML now sets the clock multiplier to 2100x.

- Dan

Hannah Pinkos

unread,
Mar 28, 2016, 10:32:25 AM3/28/16
to cesium-dev
Thanks for sharing, Dan!  That demo looks really great!

-Hannah
Reply all
Reply to author
Forward
0 new messages