Rotations

Discussion forum for Celestia developers; topics may only be started by members of the developers group, but anyone can post replies.
Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Post #41by chris » 14.11.2006, 06:23

selden wrote:I just now tried the corrected SSC on my system at work and it doesn't show the flicker/location problem. It isn't running the most recent CVS version of Celestia, though: i forgot to upload that from home. I also might have made a typo somewhere. I'll double check everything when I get home this evening.


Let me know if you're still seeing a problem . . . Sync orbit is working fine for me.

--Chris

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 2 months
Location: NY, USA

Post #42by selden » 14.11.2006, 11:50

Very strange.

It still flickers on my home computer.
Apparently there is something different between the configuration of Celestia on my computer at home and the one at work.

i'll copy the whole directory tree and take it to work to see what happens.

I rebuilt Celestia.
Downloaded the zip file and made the Center corrections.
Ran the new version of Celestia.
Used the html file's url to go to the viewpoint
enabled simulation time (\)
and the Z orientation flickers. The other three don't.

[edit]
[10:30 am U.S. EST]

It also flickers on my computer at work when I use an exact copy of the Celestia directory that I use at home.
Investigation continues..

[10:53 am us est]
I discovered a typo in the SSC used for the non-flickering model. It specified
Center "Sol/Object"
It should have specified
Center "Sol/vecalignz"

When that was corrected, the Z model started flickering.

[11:20 am us est]
I changed the trajectory files so that they don't point directly toward the origin. No change: the Z object still flickers.

I changed the Secondary vector to specify "x" instead of "y".
New problem: The model is not drawn at all, although there is no error message in the console log file.

Just to test, I changed the Secondary vector to specify "z", the same as the Primary vector. Celestia correctly complains that the two vectors are colinear.

[11:45 edt]

I changed the trajectories again so that their initial end is much farther away from the origin. Now things seem to be OK.

Apparently the problems I've been seeing are indeed related to how closely a trajectory points toward or away from the origin. While this particular situation is artificial, I suspect that some real trajectories will have segments that point near the origin.

It'd be nice if the a more stable algorithm could be used.
[/edit]
Selden

produit
Posts: 9
Joined: 29.08.2006
With us: 18 years 2 months
Location: Geneva, Switzerland

Post #43by produit » 17.11.2006, 15:05

Hi,

thanks to Chris I am able to run on Mac
something that show version 1.4.2(0)
I am able to load the .xyz file and the .q file for INTEGRAL.
By the way they have to be in the data subdirectory
otherwise they are not found (even if the ssc file is
happy to be in extra/integral)
using this .ssc:
# This file contains the orbital elements in Celestia's SSC format.
# for ESA's INTEGRAL satellite
#
# The information was obtained from JPL's Horizons ephemeris server
# Nov 22. 2002.
# by Selden Ball seb+cel@lns.cornell.edu
#
# Integral satellite model courtesy of
# <a href="http:sci.esa.int/integral">ESA</a>
#
"INTEGRAL" "Sol/Earth"
{
Class "spacecraft"
Mesh "integral.cmod" # warning: 5MB
Radius 0.003 #4x4x6 meters w/o solar panels
# EllipticalOrbit
# {
#2452600.500000000 = A.D. 2002-Nov-22 00:00:00.0000 (CT)
# EC= 8.234577927435308E-01 QR= 1.548414639838864E+04 IN= 5.305319831508738E+01
# OM= 1.014890638402147E+02 W = 3.024416289547550E+02 Tp= 2.452599790605179E+06
# N = 1.203225930959157E+02 MA= 8.535622442451043E+01 TA= 1.613366092163504E+02
# A = 8.770790078484899E+04 AD= 1.599316551713093E+05 PR= 2.991956794955576E+00
# Period 2.991956794955576E+00
# SemiMajorAxis 8.770790078484899E+04
# Eccentricity 8.234577927435308E-01
# Inclination 5.305319831508738E+01
# AscendingNode 1.014890638402147E+02
# ArgOfPericenter 3.024416289547550E+02
# MeanAnomaly 8.535622442451043E+01
# Epoch 2452600.5
# }
Albedo 0.7
SampledOrbit "integral_orbit.xyz"
SampledOrientation "integral.q"
BodyFrame { EquatorJ2000 { Center "Sol/Earth" } }
}

and integral.q and integral.xyz that can be found on my web site:
http://isdc.unige.ch/~produit/celestia

I was able to correct the initial errors
(it seems x and y axis in the model are swapped and z=-z
according to INTEGRAL official nomenclature)
and now I think they are accurate.
Orbit cover up to october 2006 but attitude are coverred only up to
Oct 2004. I am running the rest it will be ready next week.
I will see how to update them regularly.

Thanks a lot
Nicolas Produit

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 2 months
Location: NY, USA

Post #44by selden » 17.11.2006, 15:43

Nicolas,

That's great!
Selden

rthorvald
Posts: 1223
Joined: 20.10.2003
With us: 21 years 1 month
Location: Norway

Post #45by rthorvald » 12.01.2008, 22:22

I don??t really understand this material, and want to change a ships orientation during its flight. I want the orientation to start with:

-149 -1.9 -0.56 0.65 at date 2447480.626960

and end with:

-91 -1.9 -0.16 1.35 at date 2447480.627000

... How can i do that with these functions? Can someone demonstrate?

I have a series of values ready, but the only way to do it old-fashioned is by using beginning and ending dates for the SSC object for each increment. While that is easy to do, it makes a huge SSC file, and it would be nice to avoid that...

Thanks,
- rthorvald
Image

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 2 months
Location: NY, USA

Post #46by selden » 12.01.2008, 22:48

Runar,

I'm not sure what values you are specifying, but if they're the components of a quaternion, you can use a .q file. It's similar to an xyz file but contains the object's orientation values specified as a quaternion for each specified time. Each orientation specification consists of five numbers:

date q.w q.x q.y q.z

date is the Julian date,
and the q.? values are the 4 components of the object's orientation specified as a quaternion relative to the object's BodyFrame.

Quaternion (.q) files are convenient when an object's orientation changes irregularly but at known times. (I've never actually used a .q file. I may have the order of the quaternion components wrong.)

If the object's orientation changes smoothly or can be calculated from the positions and/or orientations of other objects, it might be more appropriate to use a ScriptedRotation function instead. (I've used them a lot.)
Selden

rthorvald
Posts: 1223
Joined: 20.10.2003
With us: 21 years 1 month
Location: Norway

Post #47by rthorvald » 12.01.2008, 23:21

selden wrote:Runar,
I'm not sure what values you are specifying, but if they're the components of a quaternion, you can use a .q file
This is regular orientation values = [ angle x y z ].

selden wrote:If the object's orientation changes smoothly or can be calculated from the positions and/or orientations of other objects, it might be more appropriate to use a ScriptedRotation function instead. (I've used them a lot.)


It is meant to be a smooth transition from one angle to another for a spaceship that enters orbit. I haveto change its orientation once manually before i can let it use the BodyFrame declaration to keep it oriented the rest of the flight.

It sounds like ScriptedRotation is what i want. I will investigate...

Thanks,
Runar
Image

rthorvald
Posts: 1223
Joined: 20.10.2003
With us: 21 years 1 month
Location: Norway

Post #48by rthorvald » 12.01.2008, 23:35

Selden,
I read through the wikibook about scriptingrotation, looked at some posts here in the forums and also downloaded and examined your example, here:
http://www.lepp.cornell.edu/~seb/celest ... ripted.zip

... Regrettably, i don??t understand it. Are you or someone else able to show me how to use my values in this function?

- rthorvald
Image

Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Post #49by chris » 13.01.2008, 00:10

rthorvald wrote:
selden wrote:Runar,
I'm not sure what values you are specifying, but if they're the components of a quaternion, you can use a .q file
This is regular orientation values = [ angle x y z ].

selden wrote:If the object's orientation changes smoothly or can be calculated from the positions and/or orientations of other objects, it might be more appropriate to use a ScriptedRotation function instead. (I've used them a lot.)

It is meant to be a smooth transition from one angle to another for a spaceship that enters orbit. I haveto change its orientation once manually before i can let it use the BodyFrame declaration to keep it oriented the rest of the flight.

It sounds like ScriptedRotation is what i want. I will investigate...


Actually, I think that a SampledOrientation with just two quaternions is what you want. You could do something similar with a ScriptedRotation, but that's more too complex for a simple interpolation. You just need to convert the axis-angle rotations into quaternions. For an axis angle rotation

[ angle, ax, ay, az ]

the equivalent quaternion is

[ c, s*ax, s*ay, s*az],
where c = cos(angle / 2) and s = sin(angle / 2)

This is only true when the axis is normalized to unit length, which is not the case for your values. To normalize the axis, divide each component by sqrt(ax*ax + ay*ay + az*az):

Thus for -149 -1.9 -0.56 0.65:

sqrt(ax*ax + ay*ay + az*az) = 2.085

The normalized axis is then [ -0.911 -0.269 0.312 ]

Calculating the quaternion using the angle and the normalized axis:
s = sin(-149 / 2) = -0.963
c = cos(-149 / 2) = 0.267

c = 0.267
s*-0.911 = 0.877
s*-0.269 = 0.259
s *0.312 = 0.300

So the first record in your sampled orientation file should be:

2447480.626960 0.267 0.877 0.259 0.300

Repeat the calculations for the end rotation . . .

--Chris
Last edited by chris on 13.01.2008, 00:43, edited 1 time in total.

rthorvald
Posts: 1223
Joined: 20.10.2003
With us: 21 years 1 month
Location: Norway

Post #50by rthorvald » 13.01.2008, 00:22

chris wrote:[Repeat the calculations for the end rotation . . .


Many thanks for your example and explanation, Chris!

Unfortunately, i have no math at all. Incredible as it seems, i do not know what sqrt, sin or cos means.... I really do not know how to do this in a calculator. Sorry for being this ignorant, but i can??t do it.

- rthorvald
Image

Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Post #51by chris » 13.01.2008, 00:46

rthorvald wrote:
chris wrote:[Repeat the calculations for the end rotation . . .

Many thanks for your example and explanation, Chris!

Unfortunately, i have no math at all. Incredible as it seems, i do not know what sqrt, sin or cos means.... I really do not know how to do this in a calculator. Sorry for being this ignorant, but i can??t do it.

- rthorvald


When I get a spare moment, I'll write a quick little JavaScript converter to take care of it all.

--Chris

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 2 months
Location: NY, USA

Post #52by selden » 13.01.2008, 00:55

Runar,

How did you calculate the values that you have?
Usually a ScriptedRotation would use that calculation rather than the values.

Here's a relatively simple example of a ScriptedRotation taken from my Hale Telescope Addon. I like to separate the calculation functions (BridgeRot in this example)
from the Lua ScriptedRotation functions (BridgeRotate in this example).
This is primarily to help me when I'm editing them.
It helps to limit the damage when I make typos.

Debugging Scripted functions is extremely difficult.
The usual symptom is just that they do nothing.
In some cases, when the code structure is invalid,
there will be an error message in Celestia's console output,
but usually there's nothing: the syntax is valid but there's a typo somewhere.

Code: Select all


-- Bridge up/down

BridgeRot = function ( date )

    local Angle;
   if     (date < Bridge.T0)
     then  Angle = Bridge.Th0
        elseif (date < Bridge.T1)
           then   Angle = Bridge.Th0 + Bridge.V*(date-Bridge.T0)
   else    Angle = Bridge.Th1
         end

    return  zPi * celestia:newrotation( xAxis, Angle)
end

-- ==========================================================
-- BridgeRotate -- rotate mirror Bridge

BridgeRotateProto = { } -- no args

-- constructor method

function BridgeRotateProto:new(o)
   o = o or {}
   setmetatable (o, self)
   self.__index = self

   o.period = 1

   return o
end

-- orientation function

function BridgeRotateProto:orientation(tjd)

   local qNow = BridgeRot( tjd )
   return qNow.w, qNow.x, qNow.y, qNow.z

end

-- create new rotation object

function BridgeRotate(sscvals)

   return BridgeRotateProto:new(sscvals)

end

Using this code,
the telescope's Coude bridge stays at its initial orientation (Bridge.Th0)
while the current date is less than the time when it's supposed to start moving,
moves while the current date is less than the time when it's supposed to stop moving,
and stays at the final orienation (Bridge.Th1) otherwise,
i.e. while the current date is greater than or equal to the time when it's supposed to stop moving.


Here's the Bridge's SSC declaration:

Code: Select all

# the arch which carries a flat to divert light back toward the yoke's axis
# when the direct path is blocked

"hale_coude_bridge" "Sol/Earth/hale_telescope" {

   Mesh "hale_coude_bridgefix.cmod"

   Radius 0.03

   OrbitFrame { BodyFixed { Center "Sol/Earth/hale_yoke" } }
   FixedPosition   [0 0.001875 -0.00731]

   BodyFrame  { BodyFixed { Center "Sol/Earth/hale_yoke" } }
   ScriptedRotation
   {
      Module "hale_control"
      Function "BridgeRotate"
   }

   Albedo 0.00001
}



Background for the SSC declaration:

The Bridge is carried around by the telescope's Yoke, which is defined elsewhere.
The ScriptedRotation "BridgeRotate" only has to worry about how the bridge turns relative to the yoke.

Background for the ScriptedRotation:

The current orientation angle of the bridge is calculated from its initial orientation angle and its velocity using the formula taught in introductory physics:

x = x0 + v*t

(the current position of a body is the body's initial position plus
the velocity it's moving multiplied by the amount of time that it's been moving.)

The "coude bridge" is rotating in a single plane around its X axis.

The values used in the calculation are globals defined elsewhere.

Bridge.T0 is when it started moving
Bridge.Th0 is its starting orientation angle
Bridge.V is its rotational velocity
Bridge.Th1 is its final orientation angle.

I precalculated the velocity from Th0 and Th1.
I decided the values for Th0 and Th1 in advance by knowing where the bridge had to be in order to reflect the light in the correct direction.
The time is arbitrary: it's how long I wanted the movement to take.
It happens to be 10 seconds, which is unrealistically fast,
but is an amount of time that I think people will be willing to watch things move.

V = distance/time = (Th1-Th0)/(duration of motion)
(This movement function is a simplification, since there really should be accelerations at the start and end of the bridge's movement.
I decided not to include them since nobody would notice.)

zPi is a quaternion defining a 180 rotational offset around the Z axis to compensate for an offset in the model's orientation.
You may or may not need to include an offset like this depending on how your models are designed.

xAxis a vector defining the direction of the X axis, which is what the Bridge rotates around.


Here are the definitions I used for the globals.
You'll want to determine yours some other way, I'm sure, and should structure your code differently, too.
I'm not a very good OO programmer: I'm an old Fortran programmer.

Code: Select all

-- initial global values

second =  0.11574074051168E-04

-- arbitrary duration for all movements. For some it's too slow, for others it's too

fast.
dT = 10*second

-- axes and fixed rotations around them

xAxis = celestia:newvector( 1, 0, 0)
yAxis = celestia:newvector( 0, 1, 0)
zAxis = celestia:newvector( 0, 0, 1)
  xPi = celestia:newrotation( xAxis, math.pi)
  yPi = celestia:newrotation( yAxis, math.pi)
  yR0 = celestia:newrotation( yAxis, 0)
  zPi = celestia:newrotation( zAxis, math.pi)


Bridge = {}
Bridge.T0 = 1e18
Bridge.T1 = 0

Bridge.Down = math.rad(90.0)-math.rad(180)
Bridge.Up   = math.rad(-20) -math.rad(180)
Bridge.Th1 = Bridge.Up
Bridge.Th0 = Bridge.Down
Bridge.V = 0

RaiseBridge = function (mydate)
   Bridge.Th0 = Bridge.Down
   Bridge.Th1 = Bridge.Up
        Bridge.V = (Bridge.Th1 - Bridge.Th0)/ dT
   Bridge.T0 = mydate
   Bridge.T1 = mydate+dT
end

LowerBridge = function (mydate)
   Bridge.Th0 = Bridge.Up
   Bridge.Th1 = Bridge.Down
        Bridge.V = (Bridge.Th1 - Bridge.Th0)/ dT
   Bridge.T0 = mydate
   Bridge.T1 = mydate+dT
end


For my functions, the starting time (mydate) is learned at runtme when the user types a command. If the timings of your objects' motions are predetermined, then you could code them in as constants or pass them as arguments to the ScriptedFunction.
Selden

ElChristou
Developer
Posts: 3776
Joined: 04.02.2005
With us: 19 years 9 months

Post #53by ElChristou » 13.01.2008, 00:55

chris wrote:...When I get a spare moment, I'll write a quick little JavaScript converter to take care of it all...


Hey, that would be really nice! Tx Chris!
Image

rthorvald
Posts: 1223
Joined: 20.10.2003
With us: 21 years 1 month
Location: Norway

Post #54by rthorvald » 13.01.2008, 00:55

chris wrote:When I get a spare moment, I'll write a quick little JavaScript converter to take care of it all.


Hey, that would really be great! Thank you!

Next question, then... The last one for this subject: can i do the same thing with RotationOffset?

- rthorvald
Image

rthorvald
Posts: 1223
Joined: 20.10.2003
With us: 21 years 1 month
Location: Norway

Post #55by rthorvald » 13.01.2008, 00:59

selden wrote:How did you calculate the values that you have?
Usually a ScriptedRotation would use that calculation rather than the values.


I manually rotated the object until it had the right angle. Then i wrote a series of ssc definitions with beginning and ending dates for each iteration and changed the rotation slightly for each step by hand. Now i have a series, with dates, that i want to create a simpler SSC file for, or its going to be huge...

Thank you for your example here, i will study it in detail.

- rthorvald
Image

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 2 months
Location: NY, USA

Post #56by selden » 13.01.2008, 01:15

One of many warnings :)

My code assumes that time is continuously advancing.
It does bizarre things when time is reversed.
Selden

Avatar
Adirondack M
Posts: 528
Joined: 01.03.2004
With us: 20 years 8 months

Post #57by Adirondack » 13.01.2008, 14:05

rthorvald wrote:Next question, then... The last one for this subject: can i do the same thing with RotationOffset?
Runar, FYI:
RotationOffset becomes MeridianAngle in UniformRotation (and Precessing Rotation) in 1.5.0+.

Adirondack
We all live under the same sky, but we do not have the same horizon. (K. Adenauer)
The horizon of some people is a circle with the radius zero - and they call it their point of view. (A. Einstein)

Avatar
Adirondack M
Posts: 528
Joined: 01.03.2004
With us: 20 years 8 months

Post #58by Adirondack » 13.01.2008, 14:29

chris wrote:Actually, I think that a SampledOrientation with just two quaternions is what you want.
--Chris
Ehm, Chris, you are talking about SampledRotation, or did I miss something?

Adirondack
We all live under the same sky, but we do not have the same horizon. (K. Adenauer)

The horizon of some people is a circle with the radius zero - and they call it their point of view. (A. Einstein)

Avatar
selden
Developer
Posts: 10192
Joined: 04.09.2002
With us: 22 years 2 months
Location: NY, USA

Post #59by selden » 13.01.2008, 17:26

The names are inconsistent :(

Position constructs:
OrbitFrame
FixedPosition
EllipticalOrbit
CustomOrbit
SpiceOrbit
SampledOrbit
SampledTrajectory (new construct)
ScriptedOrbit

Orientation constructs:
BodyFrame
FixedRotation
UniformRotation
PrecessingRotation
SampledOrientation
ScriptedRotation

As you can also see from this list, there are some "obvious" constructs missing:

CustomRotation -- would use an internal rotation theory to make the body rotate correctly. (One is needed for the Earth, at least.)

SpiceRotation -- needed for spacecraft and target bodies.
(A minor complication is that this information is usually included in the same SPICE kernels as are used for SpiceOrbit.)
Selden

Avatar
Adirondack M
Posts: 528
Joined: 01.03.2004
With us: 20 years 8 months

Post #60by Adirondack » 13.01.2008, 23:56

I'm a little bit confused about SampledOrientation and SampledRotation.
See here and here (Chris' first posts of each thread).

Adirondack
We all live under the same sky, but we do not have the same horizon. (K. Adenauer)

The horizon of some people is a circle with the radius zero - and they call it their point of view. (A. Einstein)


Return to “Ideas & News”