The orientation of vehicles has problem when waiting in front of traffic light

1. A concise explanation of the problem you’re experiencing.

I am working on a cesium project and the goal is to display the vehicles driving according to their gpx tracks data on maps. I have generated the CZML file from gpx file where both the coordinates inside are cartographic degrees(longitude, latitude,height). The running is also no problem. But during running it looks weird that, when the vehicles are waiting in front of the traffic light, its orientation changes to a tilted degree. I uploadded a small piece of video in the attachment. Is it because of the function “entity.orientation = new Cesium.VeloctiyOrientationProperty(entity.position)”? When the vehicles are stopping for a while, the function may get no position changes? But it should not move until it get new position changes. How can I solve this? Could someone give me any help please? Thanks a lot!

2. A minimal code example. If you’ve found a bug, this helps us reproduce and repair it
var vehicleroute = Cesium.CzmlDataSource.load(’./Source/SampleData/CZMLfromSUMO_multiVeh_model.czml’);
var var_dataSource;
vehicleroute.then(function (dataSource) {
viewer.dataSources.add(dataSource);
var_dataSource = dataSource;
var entities = var_dataSource.entities.values;
for(let i=0;i<entities.length;i++){
let entity = entities[i];
entity.orientation = new Cesium.VelocityOrientationProperty(entity.position);
entity.position.setInterpolationOptions({
interpolationDegree:3,
interpolationAlgorithm: Cesium.HermitePolynomialApproximation
});
}
});

``

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

As in 1.

4. The Cesium version you’re using, your operating system and browser.

Vesion1.57

Cesium_stopping_before_traffic_light.mp4 (1.75 MB)

This very same problem has stumped me many times before! You are correct in that this is happening exactly because of the VelocityOrientationProperty using the position to compute the orientation. Intuitively, you’d think, why shouldn’t CesiumJS just keep the last known orientation if there is no change to the position?

But herein lies a problem, and it has to do with derivatives and inflection point stability. Basically, imagine your car is oriented 90 degrees when moving from A to B, but orientated 45 degrees when moving from B to C. When the car is stopped at point B, should it be facing 90 degrees or 45? Well, that depends on the last known orientation, which is going to be different depending on whether you’re playing the timeline backwards of forwards! So it’s this inconsistency, that there’s no one correct value, but that it depends on what you were doing before, that’s why Cesium avoids it by defaulting to the default orientation.

With that said, the way I’ve worked around this is to make the orientation a CompositeProperty (https://cesiumjs.org/Cesium/Build/Documentation/CompositeProperty.html?classFilter=CompositePro). In the intervals when the vehicle is moving, its value is the VelocityOrientationProperty. In the intervals when it is not moving, it is a constant orientation, facing wherever direction I (or the developer of the app) deems to be the correct one (usually the orientation it was at right before it stopped). It definitely helps to write some boilerplate code to make this more automatic if you’re doing this for several vehicles.

This is something I’ve been wanting to write a tutorial on, or improve the Cesium built in mechanisms for. Pull requests or suggestions would be definitely appreciate here! I hope you find this helpful.

Hi Omar Shehata,

thanks a lot for your answer! I now understood the derivation problem in the scene that you mean, and want to try the way of CompositeProperty which you suggested me. But should I modify the CZML file at first to set up the intervals between different stops, then I could use the CompositeProperty? I am not quite clear about how to implement this. Is there any demo code of using CompositeProperty or any explanation of implementation? That will be very helpful for me. Thank you again!

Kind regards,

Kathy

Unfortunately we don’t have a good tutorial on this yet, but you may find some helpful resources searching this forum. It looks like you can have a CompositeProperty in CZML just by defining a time interval, or you could explicitly create it with code in your application. There’s some code in this thread: https://groups.google.com/d/msg/cesium-dev/CTNlM0moR68/BReghh9iBwAJ

Hi Omar,

thanks again for your reply. Now I have modified the CZML file to set up several intervals, and set the orientation to a compositeProperty, my first step was to make the orientation as a constant value during stopping, but it didn’t work, and even the orientation of vehicle during moving became wrong. The scene is like this: A single car drives from 40sec, then stops for 25sec, and then drives to 100sec. My modification in App.js is as follows and the github project code is at: https://github.com/kathy-lee/cesium-workshop.

Could you give me any advice please? Thanks a lot!

//single vehicle case but with composite property of orientation
var vehicleroute = Cesium.CzmlDataSource.load('./Source/SampleData/CZMLfromSUMO_singleVeh.czml');
var vehicle;
var compositeOri = new Cesium.CompositeProperty();
vehicleroute.then(function (dataSource) {
    viewer.dataSources.add(dataSource);
    vehicle = dataSource.entities.getById('Point');
    vehicle.model = {
        uri: './Source/SampleData/Models/CesiumMilkTruck.gltf',
        minimumPixelSize: 12,
        maximumScale: 1000,
        silhouetteColor: Cesium.Color.WHITE,
    };
    compositeOri.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
        iso8601 : '2019-05-08T00:00:00Z/2019-05-08T00:00:39Z',
        data : Cesium.VelocityOrientationProperty(vehicle.position)
    }));
    compositeOri.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
        iso8601 : '2019-05-08T00:00:40Z/2019-05-08T00:01:25Z',
        data : 0
    }));
    vehicle.orientation = compositeOri;

    vehicle.position.setInterpolationOptions({
        interpolationDegree : 3,
        interpolationAlgorithm : Cesium.HermitePolynomialApproximation
    });
});

``

kind regards,

Kathy

Hi,

I have modified the code that the orientation of the vehicle during moving is now correct following its velocity, so I think the compositeProperty works properly. The next step is how to set the constant orientation during the stopping interval, as your answer said, usually the orientation it was at right before it stopped. So I try “var stopOri = new Cesium.ConstantProperty(movingOri.getValue(timepoint));”. But since I am a beignner in Cesium I don’t know how to get “timepoint”-- the last time point in the first interval during which the vehicle is moving. Could anyone help me? The github project link is: https://github.com/kathy-lee/cesium_traffic_model/tree/f7f858f970b5616c5d211574e27c2f8ae4538afc. Any help would be appreciated.

var vehicleroute = Cesium.CzmlDataSource.load(’./Source/SampleData/CZMLfromSUMO_singleVeh.czml’);
var vehicle;
var compositeOri = new Cesium.CompositeProperty();
vehicleroute.then(function (dataSource) {
viewer.dataSources.add(dataSource);
vehicle = dataSource.entities.getById(‘Point’);
vehicle.model = {
uri: ‘./Source/SampleData/Models/CesiumMilkTruck.gltf’,
minimumPixelSize: 12,
maximumScale: 1000,
silhouetteColor: Cesium.Color.WHITE,
};
var movingOri = new Cesium.VelocityOrientationProperty(vehicle.position);
var stopOri = new Cesium.ConstantProperty(movingOri.getValue(timepoint));
compositeOri.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
iso8601 : ‘2019-05-08T00:00:00Z/2019-05-08T00:00:39Z’,
data : movingOri
}));
compositeOri.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
iso8601 : ‘2019-05-08T00:00:40Z/2019-05-08T00:01:25Z’,
data : stopOri
}));
compositeOri.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
iso8601 : ‘2019-05-08T00:01:26Z/2019-05-08T00:01:40Z’,
data : movingOri
}));
vehicle.orientation = compositeOri;

    vehicle.position.setInterpolationOptions({
        interpolationDegree : 3,
        interpolationAlgorithm : Cesium.HermitePolynomialApproximation
    });
});

``

Hi,

I set the timepoint like this: “var stopOri = new Cesium.ConstantProperty(movingOri.getValue(Cesium.JulianDate.fromIso8601(‘2019-05-08T00:00:39Z’)));” , and it works! The orientation didn’t change any more when it stops. Next step I will try to get the time point automatically. But another problem is during different time intervals the vehicle seems suddenly disappears and then flashes back, can this be avoided? Many thanks!

Kind Regards,

Kathy

Sorry, I forgot the video attachment for this problem. Thanks!

Cesium_stopping_orientation.mp4 (4.95 MB)

Is there anyone can help me please ?

I’m assuming this is the same issue in your follow up thread here:

https://groups.google.com/d/msg/cesium-dev/shOjjgufj4M/_4P779_7BQAJ

I’ve posted a response to it, hope it helps! Feel free to continue the discussion there.