I am trying to program a 3 body problem using matlab. I was given the formula for the moon's trajectory in its rotational frame in space. It's basically the ydotdot, xdotdot=GM/(x^2+y^2)^3/2 formula. What the formula is, is not that important.
THe problem I am facing is that, I am supposed to code up a program that will numerically solve the moon's trajectory equation. I'm using ODE45 to compare with since my goal is to get the same results as ODE45. My ultimate problem is that, I want to iterate through time in terms of days so tspan= [0 365]. The thins is when I convert Gravitational constant to seconds and then do tspace= [0 365] I get a completely different result then If I were to do [0 365*3600*34] representing the seconds in a year and G= 6.67e-11. It seems that my units are very weird.
I was wondering if anyone can explain why this is happening when I use ODE 45. Why can't I convert seconds to days clearly using ODE45? Is there an extra step I have to do? The only other variables in my problem is radius, distance, and the mass of the 3 bodies.
Thank you so much. I've been working on this for a very very long time. Any help would be much appreciated.
That formula for gravitational acceleration along each axis isn't correct.
Put the earth, with mass M_e, at the origin, with the moon (mass M_m) at (x,y). Then
the earth-moon distance is given by:
R_em = sqrt(x^2 + y^2)
The total earth-moon force is given by:
F_em = G*M_e*M_m/R_em^2
The total acceleration due to Earth's gravity is given by:
a_em = F_em/M_m = G*M_e/R_em^2
and is directed toward the origin. The acceleration along
each axis is then:
xdotdot = -F_em*cos(theta) = -F_em*x/R_em = -G*M_e*x/R_em^(3/2)
ydotdot = -F_em*sin(theta) = -F_em*y/R_em = -G*M_e*y/R_em^(3/2)
Note the x and y factors, which are missing from the formula you stated.
I'm not sure what you mean by "converting the gravitational constant to seconds".
The value you're using for G has units of newton-meter^2/kg^2. So it's already
expressed in the MKS (meter-kilogram-second) system, and the accelerations calculated
using this value will have units of meters/sec^2.
With a third body (say, the sun) at (x_s, y_s), you compute a new R_s representing
the moon-sun distance, and compute new acceleration vectors as above, using the
sun's mass M_s (except the acceleration is now in the direction of (x_s, y_s), rather than (0,0)). The accelerations of the moon from the gravity of the earth and the sun just add component-wise, once everything is put into a common coordinate system (here,
geocentric coordinates -- although heliocentric might be a more convenient choice, if you're simulating the sun-earth-moon system). That, plus the initial positions and velocities, should be all you need to compute the positions and velocities at the next time step.
Related
I am currently working on a project (for fun) for simulating Newtonian gravity and want to be able to visualize the future path of an object orbiting around a single attractor. At any given simulation step I know
The object's current position relative to the center of the attractor as a 2D Vector
The object's current velocity as a 2D Vector
The mass of the attractor
The mass of the object
Using these parameters I would like to be able to predict up to N steps ahead in the simulation so that I can draw a line between each point along the orbit.
The Position and Velocity in my simulation are measured in m and m/s while the mass is unitless. The Gravitational Constants is set to 1 and the masses for each object is 1000, for the attractor, and 10 for the object.
The simulation itself produces the result that I want, now I just want to be able to predict the future path.
During my own research, I have found that I need to use the Keplerian Elements in some way. The various examples, questions etc... I have found on stackexchange and elsewhere do not provide sufficient explanation for me to be able to work it into my simulation or they are specific for 3-dimensional geometry and provide incorrect outputs when I attempt to calculate them (NaN and Infinities).
For example, in a few places I have read that the semi-major axis and the total orbital energy should remain constant and from these I can get the eccentricity and various other properties, but when calculating them at any given step using the above-mentioned properties I have access to, they vary wildly or produce numbers that are so ridiculously high or low that they are essentially useless. I resolved the last problem and have a semi-major axis value that makes sense in the context of my simulation, but again it varies from step to step.
As an example:
Initial conditions
Attractor
Mass = 1000
Position = 0,0
Object
Mass = 10
Position = 5, 0
Velocity = 0, 5
This produces an elliptical orbit. The semi-major axis should remain constant as no other forces are acting on the object, however, the value of the semi-major axis varies from 2-4 meters.
I have figured it out and to any future visitors to this question I am (hopefully) going to make your life much, much easier.
If you are like me, fairly lay in terms of astrodynamics then the sheer number of equations, their very technical explanations, and usage is a little daunting. With a little bit of effort, I now know how to iterate equations to be able to calculate future orbital positions.
What we will need are the velocity and positional coordinates of the object you want to predict as well as the mass of the orbital body and the mass of the object itself.
These need to be in m and m/s for no other reason than for this implementation they are assumed to be m and m/s but the mass can be unitless (at first).
Terms:
Attractor - The nearest massive body that is attracting the Object.
Object - The orbital body that is being attracted to the Attractor.
Step 1: Calculate the True Mass of your objects
True mass is defined as the KG mass of your Attractor and Object. To find this value you need to convert your unitless mass, using the gravitational constant, into kilograms.
If you don't know how to do this, first calculate the ratio of unitless mass to the gravitational constant in your simulation and use the value of that ratio to find true mass using the real gravitational constant.
(I cannot post images or else I would include the equations)
After this point when I refer to the gravitational constant, I will be using our real universe's value.
Step 2: Calculate μ
μ is a ratio of masses and the gravitational constant. If the mass of the attractor is large enough μ = GM, where G is the gravitational constant and M is the mass of the attractor. For my own implementation I found that μ can be calculated as:
μ = G ( M * M * M) / ((M+m)*(M+m))
Where:
M is the mass of the Attractor
m is the mass of the Object
G is the gravitational constant.
It is very very important that this value is correct. If what you are rendering looks weird, it is probably because this value was not calculated correctly and it would be the first thing I check. In my initial attempts, this was off by an order of magnitude, it should have been around 100 but it was outputting as 1000 because the mass unit conversion value I calculated was 10x larger than it should have been.
Step 3: Calculate the Orbital Elements
First up is the Semi-Major Axis. This is the radius from the furthest point in the orbit to the center (Aprox). It is represented with the symbol a and calculated as:
a = -(μ * len(pos)) / (len(pos) * len(vel) * len(vel) - (2 * μ))
Man I wish I could post images so these equations looked better, sorry!
Next up is the period of the orbit. This is used later so that we can step through the orbit incrementally. It is represented by the symbol T and its formula is:
T = 2 * π * sqrt((a * a * a) / μ)
Next, we need angular momentum. Now, I know that the post says 2D but in my own code, I am using Vector3's to store my information in case I decide to make it 3D later. This is important because normally to get the angular momentum you would take the cross product of the velocity and position. Since we are in 2D there is no true cross product for vectors. Instead, you can calculate the momentum as:
p = pos.x * vel.y - pos.y * vel.x
Now onto orbital energy, represented by the symbol ε. We use this to find the eccentricity of the orbit.
ε = (len(vel) * len(vel)) / 2 - (μ / len(pos))
After that we can get eccentricity, represented with the symbol e:
e = sqrt(1 + ((2 * ε * p * p) / (μ * μ)))
The second to last thing we need to calculate is the eccentricity vector, represented with ev:
ev = ((((len(vel) * len(vel)) / μ) - (1 / len(pos))) * pos) - ((dot(pos, vel) / μ) * vel)
I know, there are a lot of brackets but I want to make it clear what goes where. Blame StackOverflow for not letting me post equation images.
The final value is the argument of periapsis. Because we are in 2D we need to use this formula to calculate it:
w = atan2(ev.y, ev.x)
we will use this to orient our orbital path correctly.
Step 4: Keplers Equation
Now is where we get to predict the orbital positions using all the information we calculated above.
First, we need n. n is the radians / second that the Object is traveling around the Attractor. It is fairly straightforward to calculate, it is 2π/T where T is the period. This value is used when we calculate the mean anomaly in the predictive step.
Now we get into the loop. You can set the number of steps you want to integrate over to whatever you want, the higher the number the closer each point along the orbit will be. In my case, I have a step of 100, so in my for loop declaration, I will loop 100 times before exiting. In addition, you will want to define a max tries value because we need to do an integration (don't worry, not as scary as it sounds) to be able to get the correct Eccentric Anomaly.
Now that we are in the loop, we need to calculate the current mean anomaly:
ma = n * (T * (i / steps))
Where:
T is the period of the orbit in seconds
i is the current iterative step
n is speed from earlier (radians/second)
Now we do the integration to solve Kepler's Equation. This can be done using Newton's method. Basically, we take Kepler's Equation and its derivative and iterate over them until the delta value between the two of them is arbitrarily low.
This is why we need max tries, it is possible that this while loop iterates forever and never converges on a value in which case we need to bail out so we don't get stuck.
//Eccentric Anomaly
var ea = ma;
while(tries < maxTries)
{
tries++;
//Keplers equation
var dx = ea - e * sin(ea) - ma;
//Derivative of Keplers equation
var dy = 1 - e * cos(ea);
var dt = dx / dy;
ea -= dt;
if(abs(dt) < 10^-8) break;
}
See, the integration wasn't so hard. This loop is an implementation of Newton's method and will oscillate toward to correct value. It should be noted that his method is quick and dirty and produces okay results. But this is the only method I understand so this is why I used it.
Step 5: Calculating Orbital Position
Next up is where we calculate the orbital position. This is simple and I stole it directly from this post.
p = a * (cos(ea) - e)
q = a * sin(ea) * sqrt(1 - (e * e))
You can plot these two values as X and Y and you will get an orbit that looks correct in some cases, but we need to rotate it using the argument of periapsis we calculated earlier. Again, stolen from this post.
x = cos(w) * p - sin(w) * q
y = sin(w) * p - cos(w) * q
And that's it. You're done. You have the X and Y coordinate at the current step and you can plot it on the screen however you like. As the for loop continues to iterate, you will get the full orbital path from start to finish.
I hope this essay helps someone out there!
All the equations I used can be found on Wikipedia just by going to this page and navigating to the corresponding element.
Being neither great at math nor coding, I am trying to understand the output I am getting when I try to calculate the linear distance between pairs of 3D points. Essentially, I have the 3D points of a bird that is moving in a confined area towards a stationary reward. I would like to calculate the distance of the animal to the reward at each point. However, when looking online for the best way to do this, I tried several options and get different results that I'm not sure how to interpret.
Example data:
reward = [[0.381605200000000,6.00214980000000,0.596942400000000]];
animal_path = = [2.08638710671220,-1.06496059617432,0.774253689976102;2.06262715454806,-1.01019576900787,0.773933446776898;2.03912411242035,-0.954888684677576,0.773408777383975;2.01583648760496,-0.898935333316342,0.772602855030873];
distance1 = sqrt(sum(([animal_path]-[reward]).^2));
distance2 = norm(animal_path - reward);
distance3 = pdist2(animal_path, reward);
Distance 1 gives 3.33919107083497 13.9693378592353 0.353216791787775
Distance 2 gives 14.3672145652704
Distance 3 gives 7.27198528565078
7.21319284516199
7.15394253573951
7.09412041863743
Why do these all yield different values (and different numbers of values)? Distance 3 seems to make the most sense for my purposes, even though the values are too large for the dimensions of the animal enclosure, which should be something like 3 or 4 meters.
Can someone please explain this in simple terms and/or point me to something less technical and jargon-y than the Matlab pages?
There are many things mathematicians call distance. What you normally associate with distance is the eucledian distance. This is what you want in this situation. The length of the line between two points. Now to your problem. The Euclidean distance distance is also called norm (or 2-norm).
For two points you can use the norm function, which means with distance2 you are already close to a solution. The problem is only, you input all your points at once. This does not calculate the distance for each point, instead it calculates the norm of the matrix. Something of no interest for you. This means you have to call norm once for each row point on the path:
k=nan(size(animal_path,1),1)
for p=1:size(animal_path,1),
k(p)=norm(animal_path(p,:) - reward);
end
Alternatively you can follow the idea you had in distance1. The only mistake you made there, you calculated the sum for each column, where the sum of each row was needed. Simple fix, you can control this using the second input argument of sum:
distance1 = sqrt(sum((animal_path-reward).^2,2))
What is the fitness function used to solve an inverted pendulum ?
I am evolving neural networks with genetic algorithm. And I don't know how to evaluate each individual.
I tried minimize the angle of pendulum and maximize distance traveled at the end of evaluation time (10 s), but this won't work.
inputs for neural network are: cart velocity, cart position, pendulum angular velocity and pendulum angle at time (t). The output is the force applied at time (t+1)
thanks in advance.
I found this paper which lists their objective function as being:
Defined as:
where "Xmax = 1.0, thetaMax = pi/6, _X'max = 1.0, theta'Max =
3.0, N is the number of iteration steps, T = 0.02 * TS and Wk are selected positive weights." (Using specific values for angles, velocities, and positions from the paper, however, you will want to use your own values depending on the boundary conditions of your pendulum).
The paper also states "The first and second terms determine the accumulated sum of
normalised absolute deviations of X1 and X3 from zero and the third term when minimised, maximises the survival time."
That should be more than enough to get started with, but i HIGHLY recommend you read the whole paper. Its a great read and i found it quite educational.
You can make your own fitness function, but i think the idea of using a position, velocity, angle, and the rate of change of the angle the pendulum is a good idea for the fitness function. You can, however, choose to use those variables in very different ways than the way the author of the paper chose to model their function.
It wouldn't hurt to read up on harmonic oscillators either. They take the general form:
mx" + Bx' -kx = Acos(w*t)
(where B, or A may be 0 depending on whether or not the oscillator is damped/undamped or driven/undriven respectively).
Please can you help me understand how to calculate the Mean-Squared Displacement for a single particle moving randomly within a given period of time. I have read a lot of articles on this (including Saxton,1991,Single-Particle Tracking: The Distribution of Diffusion Coefficients), but still confused (not getting the right answer).
Let me start by showing you how I do it and please correct me if I'm wrong:
The way I'm doing it is as follows:
1.Run the program from t=0 to t=100
2.Calculate the displacement, (s(t)-s(t+tau)), at each timestep (ie. at t=1,2,3,...100) and store it in a vector
3.Square the answer to number 2
4.find the mean to the answer of 3
In essence, this is what I'm doing in Matlab
%Initialise the lattice with a square consisting of 16 nonzero lattice sites then proceed %as follows to calculate the MSD:
for t=1:tend
% Allow the particle to move randomly in the lattice. Then do the following
[row,col]=find(lattice>0);
centroid=mean([row col]);
xvec=[xvec centroid(2)];
yvec=[yvec centroid(1)];
k=length(xvec)-1; % Time
dt=1;
diffx = xvec(1:k) - xvec((1+dt):(k+dt));
diffy = yvec(1:k) - yvec((1+dt):(k+dt));
xsquare = diffx.^2;
ysquare = diffy.^2;
MSD=mean(xsquare+ysquare);
end
I'm trying to find the MSD in order to compute the diffusion co-efficient. Note that I'm modelling a collection of lattice sites (16) to represent a single particle (more biologically realistic), instead of just one. I have been brief with the comment within the for loop as it is quite long, but I'm happy to send it to you.
So far, I'm getting very small MSD values (in the range of 0.001-1), whereas I'm supposed to get values in the range of (10-50). The particle moves very large distances so surely my range of 0.001-1 cannot be right!
This is an extract from the article which I'm trying to reproduce their figure:
" We began by running some simulations in 1D for a single
cell. We allowed the cell to move for a given number of
Monte Carlo time steps (MCS), worked out the mean square
distance traveled in that time, repeated this process 500
times, and evaluate the mean squared distance for this t.
We then repeated this process ten times to get the mean of
. The reason for this choice of repetitions was to
keep the time required to run the simulations within a reasonable
level yet ensuring that the standard deviation of the
mean was relatively small (<7%)".
You can access the article here "From discrete to a continuous model of biological cell movement, 2004, by Turner et al., Physical Review E".
Any hints are greatly appreciated.
How many dimensions does the particle move along ?
I don't have Matlab right now, but here is how I'd do that over one dimension :
% pos is the vector of positions
delta = pos(2:100) - pos(1:99);
meanSquared = mean(delta .* delta);
First of all, why have a particle cover multiple lattice sites? What counts for MSD, in the end, is the displacement of the centroid, which can be represented as a point. If your particle (or cell) is large, or only takes large steps, you can always just make a wider grid. Also, if you're trying to reproduce a figure from somewhere else, you should really use the same algorithm.
For your Monte Carlo simulation, what do you do? If all you really want is get a displacement, you can generate a bunch of random movement vectors in one go (using rand or randi), and use cumsum to calculate the positions. Also, have you plotted your random walks to make sure the data is sensible?
Then, your code looks a bit funny (see comments). Why don't you just use the code provided in this answer to calculate MSD from the positions?
for t=1:tend
% Allow the particle to move randomly in the lattice. Then do the following
[row,col]=find(lattice>0); %# what do you do this for?
centroid=mean([row col]);
xvec=[xvec centroid(2)];
yvec=[yvec centroid(1)]; %# till here, I have no idea what you want to do
k=length(xvec)-1; % Time %# you should subtract dt here
dt=1; %# dt should depend on t!
diffx = xvec(1:k) - xvec((1+dt):(k+dt));
diffy = yvec(1:k) - yvec((1+dt):(k+dt));
xsquare = diffx.^2;
ysquare = diffy.^2;
MSD=mean(xsquare+ysquare);
end
I have two vectors of matching lengths. They are readings from two different sensors (one is from a smartphone and the other is from a wiimote) of the same hand movement. I am trying to find the time offset between them to synchronise the readings for further processing. The readings I get are of the format (Time(ms) Value) for accelerations in the X,Y and Z direction.
For the synchronization, I plotted the cross-correlation function xcorr2() between the two sets. I am getting the same graph (a weird triangle peak and a straight line at the bottom) for Accelerations along the x, y and z directions (which I guess is good) but I don't know how to interpret it. What do the axes in the graph represent?
Can anyone explain to me what xcorr2() means in a qualitative sense. From the correlation function, how do I determine the offset (i.e. how many seconds is sensor1 behind sensor2)?
I concur with the comment made above by Predictor. To align the time series against each-other, I would pick xcorr() without the 2. Consider correlating only the acceleration magnitudes. For example:
a_mag_wii = sqrt(a_x_wii.^2 + a_y_wii.^2 + a_z_wii.^2);
a_mag_phone = sqrt(a_x_phone.^2 + a_y_phone.^2 + a_z_phone.^2);
res = xcorr(a_mag_wiimote, a_mag_smartphone);