CESIUM: How to animate an airplane from a pitch, throw, heading?

I have flight data containing position (lat, lon, height) and orientation (step, roll, course) versus time.

I would like to represent an airplane in CesiumJS.

I tried to create a CZML file from flight data. Everything worked well for the position. But the CZML format only supports orientation based on quaternion in the reference of the fixed axes of the Earth. This means that I had to preprocess this quaternion for every position, step, throw, heading in order to write CZML.

Do you think I should implement this quaternion computation (and not directly)?

Or should I use another solution to use cesium functions that allow me to use pitch, roll, heading values ​​directly ?. In this case, I am wondering what format I can use to transfer my flight data to cesium.

Thanks for your advice

+3


source to share


3 answers


I have not tried this myself, but it should be possible to convert the heading / pitch / roll of the aircraft (along the local axis of the known position of the aircraft) to a quaternion with Earth using only the math functions that come with cesium.

You have two transformations needed here, one of which is a step step to quaternion and the other is the local axes set to Earth.

Now we need a local connection with the Earth.



  1. Use Transforms.eastNorthUpToFixedFrame . This takes position into account, but gives you more than you need in a matrix view.

  2. Get only rotation from your Matrix4 using Matrix4.getRotation . This discards the transformation offset (Earth-to-plane) and gives a matrix of 3 containing only the rotation offset.

  3. Use Quaternion.fromRotationMatrix to convert your matrix3 to a quaternion.

You now have 2 quaternions, one from step 1 and the other from step 4.

  1. Multiply two quaternions together using Quaternion.multiply . The result here should be the answer you need.

Hope my math is correct. Good luck!

+1


source


The solution is similar to using sampledProperty with quaternions. There are explanations here: https://groups.google.com/forum/#!topic/cesium-dev/gb4HdaTTgXE



I haven't tried it yet, but I'll post a solution when I succeed.

0


source


I have found how to orient the model based on pitch, roll, heading versus time values. It is a pity that the SampledProperty website lacks documentation on using Cesium.Quaternion on the official website. There is also no example in sandCastle.

I modified a few lines of the example code to illustrate the orientation possibilities in cesium (copy / paste the code in HTML and JAVASCRIPT tabs in Cesium sandCastle. Only the title takes different meanings in this example, but you can play with step and roll too.

HTML CODE:

<style> 
    @import url(../templates/bucket.css); 
</style> 
<div id="cesiumContainer" class="fullSize"></div> 
<div id="loadingOverlay"><h1>Loading...</h1></div> 
<div id="toolbar"> 
    <div id="interpolationMenu"></div> 
</div> 

      

JAVASCRIPT CODE:

var viewer = new Cesium.Viewer('cesiumContainer', { 
    terrainProviderViewModels : [], //Disable terrain changing 
    infoBox : false, //Disable InfoBox widget 
    selectionIndicator : false //Disable selection indicator 
}); 

//Enable lighting based on sun/moon positions 
viewer.scene.globe.enableLighting = true; 

//Use STK World Terrain 
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ 
    url : 'https://assets.agi.com/stk-terrain/world', 
    requestWaterMask : true, 
    requestVertexNormals : true 
}); 

//Enable depth testing so things behind the terrain disappear. 
viewer.scene.globe.depthTestAgainstTerrain = true; 

//Set the random number seed for consistent results. 
Cesium.Math.setRandomNumberSeed(3); 

//Set bounds of our simulation time 
var start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); 
var stop = Cesium.JulianDate.addSeconds(start, 360, new Cesium.JulianDate()); 

//Make sure viewer is at the desired time. 
viewer.clock.startTime = start.clone(); 
viewer.clock.stopTime = stop.clone(); 
viewer.clock.currentTime = start.clone(); 
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end 
viewer.clock.multiplier = 10; 

//Set timeline to simulation bounds 
viewer.timeline.zoomTo(start, stop); 




var lon = 0; 
var lat = 45; 
var radius = 0.03; 

//Generate a random circular pattern with varying heights. 

    var positionProperty = new Cesium.SampledPositionProperty(); 
    var orientationProperty = new Cesium.SampledProperty(Cesium.Quaternion); 

    for (var i = 0; i <= 360; i += 45) { 
        var radians = Cesium.Math.toRadians(i); 
        var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate()); 

        // compute positions 
        var position = Cesium.Cartesian3.fromDegrees(lon + (radius * 1.5 * Math.cos(radians)), lat + (radius * Math.sin(radians)), Cesium.Math.nextRandomNumber() * 500 + 1750); 
        positionProperty.addSample(time, position); 

        // compute orientations 
        var heading = Cesium.Math.toRadians(90+i); 
        var pitch = Cesium.Math.toRadians(20); 
        var roll = Cesium.Math.toRadians(0);       
        var hpRoll = new Cesium.HeadingPitchRoll(heading,pitch,roll);   
        var orientation = Cesium.Transforms.headingPitchRollQuaternion(position,hpRoll); 
        orientationProperty.addSample(time, orientation); 

        //Also create a point for each sample we generate. 
        viewer.entities.add({ 
            position : position, 
            point : { 
                pixelSize : 8, 
                color : Cesium.Color.TRANSPARENT, 
                outlineColor : Cesium.Color.YELLOW, 
                outlineWidth : 3 
            } 
        }); 
    } 


//Actually create the entity 
var entity = viewer.entities.add({ 

    //Set the entity availability to the same interval as the simulation time. 
    availability : new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ 
        start : start, 
        stop : stop 
    })]), 

    //Use our computed positions 
    position : positionProperty, 

    //Automatically compute orientation based on position movement. 
    orientation : orientationProperty, 

    //Load the Cesium plane model to represent the entity 
    model : { 
        uri : '../../SampleData/models/CesiumAir/Cesium_Air.gltf', 
        minimumPixelSize : 64 
    }, 

    //Show the path as a pink line sampled in 1 second increments. 
    path : { 
        resolution : 1, 
        material : new Cesium.PolylineGlowMaterialProperty({ 
            glowPower : 0.1, 
            color : Cesium.Color.YELLOW 
        }), 
        width : 10 
    } 
}); 

//Add button to view the path from the top down 
Sandcastle.addDefaultToolbarButton('View Top Down', function() { 
    viewer.trackedEntity = undefined; 
    viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90))); 
}); 

//Add button to view the path from the side 
Sandcastle.addToolbarButton('View Side', function() { 
    viewer.trackedEntity = undefined; 
    viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(Cesium.Math.toRadians(-90), Cesium.Math.toRadians(-15), 7500)); 
}); 

//Add button to track the entity as it moves 
Sandcastle.addToolbarButton('View Aircraft', function() { 
    viewer.trackedEntity = entity; 
}); 

//Add a combo box for selecting each interpolation mode. 
Sandcastle.addToolbarMenu([{ 
    text : 'Interpolation: Linear Approximation', 
    onselect : function() { 
        entity.position.setInterpolationOptions({ 
            interpolationDegree : 1, 
            interpolationAlgorithm : Cesium.LinearApproximation 
        }); 
    } 
}, { 
    text : 'Interpolation: Lagrange Polynomial Approximation', 
    onselect : function() { 
        entity.position.setInterpolationOptions({ 
            interpolationDegree : 5, 
            interpolationAlgorithm : Cesium.LagrangePolynomialApproximation 
        }); 
    } 
}, { 
    text : 'Interpolation: Hermite Polynomial Approximation', 
    onselect : function() { 
        entity.position.setInterpolationOptions({ 
            interpolationDegree : 2, 
            interpolationAlgorithm : Cesium.HermitePolynomialApproximation 
        }); 
    } 
}], 'interpolationMenu'); 

      

0


source







All Articles