STK Attitude quaternions to CesiumJS

I’m trying to create an app to visualise a satellite’s orbit and attitude. I have both .e and .a files from STK.
However, when I try to add the orientation property to my entity, the attitude change is not what is expected. The model rotates on its own as it orbits the Earth. The model also changes size for some reason.

Here’s the entity code:

var satelliteRefined = new Cesium.Entity({
      id: satelliteId,
      position: sampledPosition,
      point: {
          pixelSize: 8,
          color: Cesium.Color.WHITE.withAlpha(0.7)
      label: {
          text: satelliteId,
          font: '14px sans-serif',
          Color: Cesium.Color.WHITE,
          pixelOffset: new Cesium.Cartesian2(0, -20) 
      model: {
          uri:  "../Models/cube.glb",
          scale: 1.0,
          minimumPixelSize: 100,
          maximumPixelSize: 1000,
          show: true
      orientation: sampledAttitude,
      path: {
          resolution: 100,
          leadTime: 3000,
          trailTime: 3000,
          material: new Cesium.PolylineOutlineMaterialProperty({
              color: Cesium.Color.WHITE.withAlpha(0.5)
          width: 3
  // Add the entity

Here’s the code I use to create the sampledAttitude property:

const lines = data.replace(/\r\n/g, ' ').split(' ').filter(function(element) {return element.trim() !== ""}).slice(19, -2)
      for (let i = 0; i < lines.length; i += 8) {
          const time = parseFloat(lines[i]);
          const x = parseFloat(lines[i + 1]);
          const y = parseFloat(lines[i + 2]);
          const z = parseFloat(lines[i + 3]);
          const w = parseFloat(lines[i + 4]);
          var orientationTime = new Cesium.JulianDate();
          const epochDate = Cesium.JulianDate.fromIso8601('1999-12-31T23:59:28.0000Z');
          Cesium.JulianDate.addSeconds(epochDate, time, orientationTime)

          attitudeData.push(Cesium.JulianDate.toIso8601(orientationTime, 2), x, y, z, w);

var sampledAttitude = new Cesium.SampledPositionProperty();
for (var i = 0; i < attitudeData.length; i += 5) {
    // Extract time, w, x, y, and z from attitudeData
    var time = attitudeData[i];
    var x = attitudeData[i + 1];
    var y = attitudeData[i + 2];
    var z = attitudeData[i + 3];
    var w = attitudeData[i + 4];
    var attitude = new Cesium.Cartesian3(x, y, z, w);
    sampledAttitude.addSample(Cesium.JulianDate.fromIso8601(time), attitude);

Is the order of quaternion components in CesiumJS different to that of STK? Is there a way to convert quaternions from STK to ones usable in CesiumJS?

Two things to look into:

  1. Do you have the scalar component of the Quaternion in the correct place? Some use a convention of scalar first, others use scalar last.

  2. Second, and more than likely your issue: Cesium uses Earth Centered Earth Fixed as its reference frame. It is expecting your quaternions to be in ECEF. If you’re saving ephemera/data files from STK then they are more than likely in the Inertial frame and you’ll need to convert them (either manually, or using STK)

Hopefully this helps!

1 Like

Also, if this is helpful have a look at this post for how I got attitude to work and be displayed in Cesium: