Orientation problem at the end path VelocityOrientationProperty

Orientation of the model changing at last position.

Can anyone please explain why the orientation changing suddenly when model out of points?

copy and paste the following code in sandcastle to test it out.

var viewer = new Cesium.Viewer("cesiumContainer");
Cesium.Math.setRandomNumberSeed(3);

//Set bounds of our simulation time
var start = Cesium.JulianDate.fromDate(new Date(new Date().getTime() - 60000));
var stop = Cesium.JulianDate.addSeconds(
  start,
  3600,
  new Cesium.JulianDate()
);

let currentTimestamp = new Date().getTime() - 6000;
//Make sure viewer is at the desired time.
viewer.clock.startTime = start.clone();
// .clock.stopTime = stop.clone();
viewer.clock.currentTime = Cesium.JulianDate.fromDate(new Date(currentTimestamp));
viewer.clock.clockRange = Cesium.ClockRange.UNBOUNDED; //Loop at the end
viewer.clock.multiplier = 1;
viewer.clock.shouldAnimate = true;

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

var position = new Cesium.SampledPositionProperty();

position.forwardExtrapolationType = Cesium.ExtrapolationType.HOLD;

var entity = viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(55.06773, 24.99495, 50),
      model: {
            uri: "../SampleData/models/CesiumMilkTruck/CesiumMilkTruck.glb",
            minimumPixelSize: 32,
            scale: 0.5,
      },  
      viewFrom: new Cesium.Cartesian3(-100.0, 0.0, 100.0),
      //position: position,  
      //orientation: new Cesium.VelocityOrientationProperty(position),
});

viewer.trackedEntity = entity;

var liveLocations = [
					[55.0673734458, 24.9945164584],
					//[55.0685952005, 24.9955737298],
					[55.0687067851, 24.9956577933],
					[55.0693178548, 24.9950571553],
					//[55.0692440368, 24.9949780376],
					[55.0683879693, 24.9942512493]
			];

var pointer = 0;
var clock = viewer.clock;
		

setTimeout(function(){

entity.position = position;
entity.orientation = new Cesium.VelocityOrientationProperty(position);
  
  
var lastUpdated = clock.currentTime;
clock.onTick.addEventListener(function () {
	var dt = Cesium.JulianDate.secondsDifference(clock.currentTime, lastUpdated);
	if (dt >= 5 && pointer < liveLocations.length) {
          console.log(pointer);
		  var location = liveLocations[pointer];
		  position.addSample(Cesium.JulianDate.fromDate(new Date()), Cesium.Cartesian3.fromDegrees(location[0], location[1]));		  
		  if(pointer < liveLocations.length) {
			  viewer.entities.add({
				  position: Cesium.Cartesian3.fromDegrees(location[0], location[1], 10),
				  point: {
					  pixelSize: 5,
					  color: Cesium.Color.RED
				  },
				  label: {
					  text: pointer + ''
				  }
			  });

		  pointer++;
		}
		lastUpdated = clock.currentTime;
	}
	
});

  
  
}, 100);

Not sure why it goes back to facing East. I’m also not sure why addEventListener is in the setTimeout function, seems to work the same not being nested within.

setTimeout(function(){
entity.position = position;
entity.orientation = new Cesium.VelocityOrientationProperty(position);
}, 100);

Perhaps you can declare and update a previous orientation, and once pointer reaches liveLocations.length just keep setting orientation to the previous orientation. Only update previous when you’re not at the end of liveLocations.

Thanks Hyper_Sonic for the explanation.

Can you please help me on how can I get last orientation?

The liveLocations array is demontration purpose, the actual scenario will be, suppose a vehicle is waiting in front of traffic light, so it’s a waiting period and I will get the same location(theoretically) from GPS at that period, but in this logic the orientation is changing even though it’s at the same location.

Can you please help me in this?

Thanks in advance.

setTimeout doesn’t seem to be needed at all, the 2 settings within could be done immediately It seems to ignore orientation settings, except for the first time, so apparently my idea won’t work. It seems to obtain orientation solely from sampled data, and ignores any other orientation settings, even when done with all of the sampled data. Perhaps it could be taken out of sampled data mode?
cesium.com/downloads/cesiumjs/releases/1.36/Build/Documentation/ExtrapolationType.html
The 2 other types don’t seem to be a good choices either: with one it just keeps going, with the other it disappears.
.

There’s some discussion about this and possible workarounds here: https://github.com/CesiumGS/cesium/issues/8900.

1 Like

I am able to alter the orientation by placing this code at the end of the event listener

	if(pointer >= liveLocations.length)
    {
      let bla = new Cesium.HeadingPitchRoll(15*Math.PI/180,-40*Math.PI/180,-60*Math.PI/180);
      entity.orientation=Cesium.Quaternion.fromHeadingPitchRoll(bla, new Cesium.Quaternion());
    }

The HPR settings don’t appear to be in relation to the local ENU frame, and I’m not sure which frame it’s in relation to. I had to mess around with different HPR values to get it facing in roughly the correct direction. If I can get a hold of the reference frame I could then easily create a desired orientation. Oh ya, the truck does turn early, the pointer reaches the end before the truck reaches the end.

Actually it can be obtained. I placed this at the top:

var firstExec=true;

Then put this at the end of event listener

if(pointer >= liveLocations.length && firstExec==true)
{
	firstExec=false;
	let bla = new Cesium.HeadingPitchRoll(0*Math.PI/180,0*Math.PI/180,0*Math.PI/180);
	entity.orientation=Cesium.Quaternion.fromHeadingPitchRoll(bla, new Cesium.Quaternion());
	let mymat = entity.computeModelMatrix(clock.currentTime);
	console.log(mymat); //this can serve as the reference matrix
}

This code is just to determine the rotation/position reference matrix. What could be done is keep saving the previous mymat (using whatever orientation exists at the time, not 0,0,0). Once it’s at the end of the route, determine the HPR values of the previous mymat in reference to the mat created by HPR 0,0,0. Then convert those HPR to quat then set the entity’s orientation. Seems a bit involved for what should be a very simple task, but if no other options are revealed…

1 Like

Thanks,

It’s working fine, but in my application there is 200+ vehicle.

Is it fine to use callback function?

is it going to reduce the performance?

Thanks in advance.

Thanks Sonic for your support,

Using the workaround in the following link solved the issue:

But I am worried about the performance as there is 200+ entities.

That callback method looks like a good idea
Should Cesium.ExtrapolationType.HOLD consider last known orientation?
I didn’t know know about the orientation.getValue(time) function. If it works that seems the way to go. I don’t see why it would be a problem for however many vehicles there are. It has to calculate the new orientation anyways, all it’s doing in addition is saving the value if defined. I wonder if the function has to be encapsulated in the callback function, can orientation just be set to an anonymous function directly?