Moving 3d Object from point A to B with velocity relative to ground speed

Hi Cesium community,

I’m new to Cesium, impressed so far with the ease of use and performance. I would like to create a prototype based the “Build a flight tracker” tutorial. I need some help on the following,

My aim is to break the waypoints into several groups and apply specific speeds to each approach. Simply put, I want to basically use the speed value in the excel sheet in the demo to control the speed of the aircraft and not rely on the animation widget. (I’m also okay to use the widget if Í can replicate the actual speed).

  1. Is it possible to move the model from A to B with constant speed, lets say 100 km/h for example.

  2. If the above is not possible, then is it possible to reach A to B within a given time duration, say within 3 minutes. Since the aim is to simulate the flight from point A to B the speed must be constant and not gradual.

What I have tried so far,

I tried looking at the time-dynamic features sandcastle. It is pretty close but not exactly what I want. In the time dynamic wheels demo, the truck accelerates from zero to 100 gradually. I would like to make it move with a constant speed. I would be perfect if I can assign speed value and say head to the destination at 300 km/r or reach the destination within 3 minutes.

Please try the Sandcastle test playground Remember to include your token.

I tried my best to explain what I’m going after. Please let me know if my explanation is not clear.

There are different ways of defining the movement of an object, both on the conceptual level and on the implementation level.

I would be perfect if I can assign speed value and say head to the destination at 300 km/r or reach the destination within 3 minutes.

These are two different ways on the conceptual level. You can say that an object should move in a certain direction, for 1 hour, with 300km/h, or you could say that an object should move from a start position to an end position that is 300km away, and this should take 1 hour.

In the most simple case, the result will be the same (and that may sound obvious). But depending on your use case, there may be details that are relevant. For example, imagine that you either have

  • an Excel table that contains entries like timeStamp, position
  • an Excel table that contains entries like timeStamp, velocityVector

You can convert them into each other, but depending on your input data and the goal, one approach may be easier than the other.

(This does not cover the real details. Imagine you want to “model” the behavior of a truck that moves 100km/h in one hour. In reality, it will not move with a constant speed. It will accelerare in the beginning, and stop at the end, and maybe drive faster than 100km/h in-between…)

However, focussing on the first steps towards a solution:

I tried looking at the time-dynamic features sandcastle. It is pretty close but not exactly what I want. In the time dynamic wheels demo, the truck accelerates from zero to 100 gradually. I would like to make it move with a constant speed.

In terms of the implementation: The example uses a SampledPositionProperty. This basically corresponds to the timeStamp, position Excel table that I mentioned above. You can define at which point in time the object should have which position, and CesiumJS will take care of moving the object.

And … you can throw anything into this SampledPositionProperty. In the Time-Dynamic Wheels sandcastle, it is filled with some “dummy data” to simulate the acceleration, at

  // Lerp using a non-linear factor so that the vehicle accelerates.
  const locationFactor = Math.pow(factor, 2);

This causes it to start at 0, and then accelerate exponentially. You just change this line to use a constant factor. For example, if you want a constant speed, then you can compute a speedFactor like this…

const desiredSpeedKmh = 45;
const distance = Cesium.Cartesian3.distance(startPosition, endPosition);
const metersPerSecond = (distance/totalSeconds);
const kilometersPerHour = metersPerSecond * (3600 / 1000);
const speedFactor = (desiredSpeedKmh / kilometersPerHour);

before the loop, and in the loop just set
const locationFactor = factor * speedFactor;

Then the truck will move with a constant speed of 45km/h.

You can see that this is computed based on the startPosition, endPosition, and the totalSeconds that the animation will take. From different input data, you could compute the appropriate positions for the SampledPositionProperty in a different way.

hi @Marco13 . Thank you for the quick response and great explanation. Sorry for the delayed reply as I wanted to make sure I tested the sample codes before replying you. Following your explanation I managed to move the truck at a constant speed of 45km/hr. Great!

I have an excel sheet which has a speed value (please take a look). I can use the technique you mentioned to make the model move at varied speeds.

Finally, one more doubt. How do reach from Point A to B with just time factor, say within 3 minutes without specifying a speed factor (at any speed)?

I still find it hard to understand a few things forgive my lack of knowledge. In the “Time Dynamic Wheels” demo, why do we need const numberOfSamples = 100; why is it set to 100 and the reason behind this?

May I check if the Cesium team is planning on improving the tutorials to cover all the basic concepts with better explanation targeting beginners? For example, the Flight tracker tutorial talks about SampledPositionProperty but not in detail. I think it is better to have detailed explanation or dedicated tutorials for important concepts like SampledPositionProperty and Callbackproperty and similar concepts.

Thanks very much.

I still find it hard to understand a few things forgive my lack of knowledge. In the “Time Dynamic Wheels” demo, why do we need const numberOfSamples = 100; why is it set to 100 and the reason behind this?

The data in that sandcastle is just “dummy data”, created at runtime, to show how the respective classes work. And in this particular case, it would work equally well with 10 or 1000. The reason why this number does not make a large difference here is that the interpolation is linear by default, and the values are also changing in a linear manner. The topics of interpolation, extrapolation, and approximation can become a bit complex pretty quickly when diving into the details. But very roughly: That number determines how many “key frames” exist, and with different (non-linear) interpolation, more points could allow to achieve a smoother motion.

Finally, one more doubt. How do reach from Point A to B with just time factor, say within 3 minutes without specifying a speed factor (at any speed)?

As I said: These representations can often be converted into each other:

  • When you have a start- and an end position, and a certain speed, then you can compute the duration as duration = distance(end - start) / speed;
  • When you have a start and an end position, and a certain duration, then you can compute the speed as speed = distance(end - start) / duration;

Looking at the Excel table that you linked to… you might have to figure out the unit of the speed column, and … well, try to make sense of it. Looking at the first two rows, it says

1559263158,0,271,37.61779,-122.39053,2179,0,0000
1559263193,0,208,37.61803,-122.39035,2179,14,0000

One could assume that the first column is a time stamp (i.e. the Unix time stamp in milliseconds), but that should be confirmed. The movement it is starting at (37.61779,-122.39053, 0) and moving to (208,37.61803,-122.39035, 0). The speed says 0 for the first row. So … it starts with a speed of 0, then obviously accelerates (until it reaches the speed of 14, from the second row). From that, again, you could make assumptions (e.g. that is is a linear acceleration), but you simply don’t know the speed that it had at any point in time, except for the given key frames.

(Note: That may sound overly complicated, but it shouldn’t be sooo hard to make sense of this data. I’m just pointing out that there are some degrees of freedom how how exactly that can be done)

May I check if the Cesium team is planning on improving the tutorials to cover all the basic concepts with better explanation targeting beginners?

I’m not aware of specific plans for tutorials in this area. It could be difficult to find the “right spot” or “right level of detail” here. For example, things like the SampledPositionProperty.interpolationAlgorithm is just an implementation of the mathematical concepts of Interpolation - so it’s not clear whether or how this should be covered in such a tutorial.

Speaking of interpolation: The Interpolation Sandcastle could be similar to what you’re trying to build, so you can probably find some inspiration there.

Hi @Marco13

It is starting to make sense to me now. I’m making some good progress.
One last hurdle to cross. Can you tell me how to make the aircraft model roll automatically based on the next point? Please refer to this image.

I’m using,

orientation: new Cesium.VelocityOrientationProperty(positionProperty),

which gives me the correct heading, and pitch but the aircraft does not roll based on the next heading/coordinates in the positionProperty.

I came across this. I don’t want to set the HPR manually. It should be based on the next position.

var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, heading, pitch, roll);

var model = scene.primitives.add(Cesium.Model.fromGltf({

url : ‘path/to/model’,

modelMatrix : modelMatrix

}));

Thank you once again for the detailed explanation and guidance. Though the tutorials are limited, the community support here is just awesome!

It’s difficult to say what might be the best approach here. (It might be easier with a sandcastle showing how you are currently using the properties, but I see that it may be difficult to “extract” this into a standalone example).

I cannot imagine how to sensibly guess a “roll” value from the positions. I’d guess that you’d like to adjust the direction that the plane is pointing to, which is usually called the heading. The heading is contained in the CSV that you linked to, and apparently can be computed automatically from the position (as shown in the Interpolation sandcastle).

Or to put it that way: I which way differs the behavior of your plane mode from that in the ‘Interpolation’ sandcastle?

I tried to transport some of the code to Sandcastle as requested by you. Please include cesium token to the demo and click play.

I have implemented interpolation like you mentioned. The results are not great except for linear (default). Both “Lagrange Polynomial Approximation” and “Hermite Polynomial Approximation” interpolation has weird rollercoaster like effects and the aircraft wont travel in the correct path. If you notice, the aircraft turns and maintains the correct heading but it is not making roll adjustments. A real aircraft will roll to left and right for turns. Like I requested earlier, I would like to implement smooth turns and roll effect. If this cannot be achieved automatically then what is the best way to make the aircraft roll? I was thinking of including the roll degrees in the JSON, in our case “flightData” object. I’m adding the model using viewer.entities.add and not scene.primitives.add , Cesium.Model.fromGltfAsync which I assume would let me add modelMatrix . Am I doing this the right way? Thanks very much.

There are usually many different ways in which a certain result can be achieved. And finding “the right” solution (or even “the best”) often requires careful analysis of the goals, knowledge about best practices, and foresight.

If the goal is only to roll the plane while it is flying, then one (simple, pragmatic) approach, based on the last sandcastle, would be:

  • Store the desired ‘roll’ angles in the input data
  • Build a SampledProperty from these angles (similarly to what you’re doing for the positions)
  • Take the VelocityOrientationProperty that you’ve already been using, and build a new “custom” orientation property based on that:
    • in each step, obtain the original orientation value
    • multiply that with a quaternion that describes the desired ‘roll’ rotation

This is what it could look like:

Cesium Plane Roll

This uses some dummy data ‘roll’ value. Figuring out the “right” ‘roll’ values is up to you.

Depending on many factors, there may be “better” approaches than that, but it is intended as a draft for one possible approach.

The sandcastle:

Wow. I didn’t know it is possible to create new “custom” Orientation property based on the VelocityOrientationProperty . Regarding the smooth turns I’m considering to generate more waypoints using turf.along and rf.midpoint for the curves (to create more frames) and adding roll values when and where necessary. This is good for now. Thanks very much @Marco13