Geostationary orbit with pyephem? - astronomy

I am trying to create a geostationary orbit in pyephem (_n = 1.0 revolutions per day). I would like to verify that it is geostationary by placing an observer directly below the satellite and verifying that alt='90.0' and az=0. For my test I am placing the observer on the equator at 100 deg W longitude. Here is my code:
import ephem
sat = ephem.EarthSatellite()
sat._n = 1.0
sat._e = 0.0
sat._inc = 0.0
sat._raan = '-100.0'
sat._ap = 0.0
sat._M = 0.0
obs = ephem.Observer()
obs.lat = 0.0
obs.lon = '-100.0'
obs.date = '2014/10/16 00:00:00'
sat.compute(obs)
print "obs position: lat=%s lon=%s date=%s" % \
(obs.lat, obs.lon, obs.date)
print "sat orbit: n=%s e=%s inc=%s raan=%s ap=%s M=%s" % \
(sat._n, sat._e, sat._inc, sat._raan, sat._ap, sat._M)
print "sat position: alt=%s az=%s ra=%s dec=%s sublat=%s sublong=%s" % \
(sat.alt, sat.az, sat.ra, sat.dec, sat.sublat.norm, sat.sublong.norm)
and the output:
> obs position: lat=0:00:00.0 lon=-100:00:00.0 date=2014/10/16 00:00:00
> sat orbit: n=1.0 e=0.0 inc=0:00:00.0 raan=-1:44:43.2 ap=0:00:00.0 M=0:00:00.0
> sat position: alt=-90:00:00.0 az=0:00:00.0 ra=6:57:44.67 dec=0:00:00.0 sublat=1389660529:33:00.8 sublong=335:33:55.8
I find that changing the observer longitude does not change the output. I expect that sat._raan sets the overhead position (sat.sublong) of the satellite, but this also has no affect on the output. I consistently get alt=-90:00:00.0 az=0:00:00.0. (Towards center of Earth) and sublat, sublong don't make any sense.
Update
The reason for the strange, unchanging output of sublat=1389660529:33:00.8 is due to the sat._epoch being '1899/12/31 12:00:00' by default, along with this issue. Setting sat._epoch = obs.date works around this, but I am still not sure how to achieve the goal of defining a geostationary orbit whose sky position is fixed above a chosen Earth coordinate.

Related

Interp1 function in ODE45

I am trying to solve a 3 Degree Of Freedom vessel-crane system in MATLAB using ode45. In my ode function, the vessel motion is determined by simple spring and damper constants, but the device below the main hoist system, a cranemaster, has a displacement-dependent stiffness and thus depends on one of the Degrees Of Freedom. To determine this value, I use the interp1 function to determine the stiffness from a dataset:
vq = interp1(x,v,xq,method,extrapolation)
This all works fine, but only when I add the extrapolation option in the interp1 function, even though the xq values all fall inside the dataset x-values. If I do not specify extrapolation, the function returns NAN.
I have checked if the stiffness values in the dataset make sense by taking the median value as a constant value and then the ode45 solver works just fine and the displacement never falls outside of the dataset. I have also noticed that if I switch to ode23 as a solver, it also works. This all makes me believe it has something to do with the solving method and the stepsize the ode solver takes as its initial value.
I have provided (a simplified version of) my code and a picture of the system to get a feel for the problem. I know that switching to ode23 solves the problem but I would like to understand why and, if possible, stay with ode45 as it is a more general solver.
Any help would be appreciated!
Regards,
Diederik
Overview of the system I am solving
close all
tspan = [0 100];
x0 = [0.0; 0; 0.0; 0; 0.0; 0]; % initial disp. and vel. is 0. for all 3 DOF.
% x = [z; zdot; theta; thetadot; u; udot]
[t,x] = ode45(#Three_DOF,tspan,x0);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plots
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure()
subplot(2,1,1)
plot(t,x(:,5),'color','b','LineWidth',1)
grid on
xlabel('Time (s)')
ylabel('Displacement (m)')
title('Displacement Vs Time')
subplot(2,1,2)
plot(t,x(:,6),'color','#D95319','LineWidth',1)
grid on
xlabel('Time (s)')
ylabel('Velocity (m/s)')
title('Velocity Vs Time')
function [dxdt] = Three_DOF(t,x)
% vessel parameters
m = 570.5e6;
m55 = 4.591e12;
mh = 200e3;
c33 = 3.83952e8;
c55 = 3.66116e12;
wnh = 0.360;
wnp = 0.596;
a33 = (c33-wnh^2*m)/wnh^2;
a55 = (c55-wnp^2*m55)/wnp^2;
zeta33 = 0.386;
zeta55 = 0.121;
b33 = zeta33*2*sqrt(c33*(m+a33));
b55 = zeta55*2*sqrt(c55*(m55+a55));
Fa = 153e6;
Ma = 3.013e9;
w1 = 0.21/0.36;
w2 = 0.18/0.28;
%%%% Cable parameters
k_c = 496e6;
b_c = 5.01e6;
%%% CRANEMASTER parameters
x_data = [-2.0; -1.87; -1.73; -1.60; -1.47; -1.33; -1.20; -1.07; -0.93; -0.8; -0.67; -0.53; -0.4; -0.27; -0.13; 0.0; 0.13; 0.27; 0.40; 0.53; 0.67; 0.80; 0.93; 1.07; 1.20; 1.33; 1.47; 1.60; 1.73; 1.87; 2.0];
k_data = [760; 792.1; 784.8; 813.9; 828.4; 850.2; 879.3; 901.1; 922.9; 959.2; 981.0; 1010.1; 1039.1; 1068.2; 1104.5; 1133.6; 1177.2; 1206.3; 1242.6; 1286.2; 1329.8; 1373.4; 1409.7; 1460.6; 1511.5; 1562.3; 1620.5; 1671.3; 1729.5; 1794.9; 1853];
k_cm = 30000*interp1(x_data,k_data,x(5));%,'linear','extrap');
%k_cm = 30000*1133.61; % middle value of dataset k_data
b_cm = 6e4;
l = 217.5;
% Matrices & solve
Mass = [m+a33 0 0; 0 m55+a55 0; 0 0 mh];
k = [c33+k_c -k_c*l -k_c; -k_c*l c55+k_c*l^2 k_c*l; -k_c k_c*l k_c+k_cm];
b = [b33+b_c -b_c*l -b_c; -b_c*l b55+b_c*l^2 b_c*l; -b_c b_c*l b_c+b_cm];
F = [Fa*sin(w1*t); Ma*sin(w2*t); 0];
EOM = Mass\(F-b*([x(2); x(4); x(6)])-k*([x(1); x(3); x(5)]));
dxdt = [x(2); EOM(1); x(4); EOM(2); x(6); EOM(3)];
% x = [z; zdot; theta; thetadot; u; udot]
end

Q values overshoot in Double Deep Q Learning

I am trying to teach the agent to play ATARI Space Invaders video game, but my Q values overshoot.
I have clipped positive rewards to 1 (agent also receives -1 for losing a life), so the maximum expected return should be around 36 (maybe I am wrong about this). I have also implemented the Huber loss.
I have noticed that when my Q values start overshooting, the agent stops improving (the reward stops increasing).
Code can be found here
Plots can be found here
Note:
I have binarized frames, so that I can use bigger replay buffer (my replay buffer size is 300 000 which is 3 times smaller than in original paper)
EDIT:
I have binarized frames so I can use 1 bit(instead of 8 bits) to store one pixel of the image in the replay buffer, using numpy.packbits function. In that way I can use 8 times bigger replay buffer. I have checked if image is distorted after packing it with packbits, and it is NOT. So sampling from replay buffer works fine. This is the main loop of the code (maybe the problem is in there):
frame_count = 0
LIFE_CHECKPOINT = 3
for episode in range(EPISODE,EPISODES):
# reset the environment and init variables
frames, _, _ = space_invaders.resetEnv(NUM_OF_FRAMES)
state = stackFrames(frames)
done = False
episode_reward = 0
episode_reward_clipped = 0
frames_buffer = frames # contains preprocessed frames (not stacked)
while not done:
if (episode % REPORT_EPISODE_FREQ == 0):
space_invaders.render()
# select an action from behaviour policy
action, Q_value, is_greedy_action = self.EGreedyPolicy(Q, state, epsilon, len(ACTIONS))
# perform action in the environment
observation, reward, done, info = space_invaders.step(action)
episode_reward += reward # update episode reward
reward, LIFE_CHECKPOINT = self.getCustomReward(reward, info, LIFE_CHECKPOINT)
episode_reward_clipped += reward
frame = preprocessFrame(observation, RESOLUTION)
# pop first frame from the buffer, and add new at the end (s1=[f1,f2,f3,f4], s2=[f2,f3,f4,f5])
frames_buffer.append(frame)
frames_buffer.pop(0)
new_state = stackFrames(frames_buffer)
# add (s,a,r,s') tuple to the replay buffer
replay_buffer.add(packState(state), action, reward, packState(new_state), done)
state = new_state # new state becomes current state
frame_count += 1
if (replay_buffer.size() > MIN_OBSERVATIONS): # if there is enough data in replay buffer
Q_values.append(Q_value)
if (frame_count % TRAINING_FREQUENCY == 0):
batch = replay_buffer.sample(BATCH_SIZE)
loss = Q.train_network(batch, BATCH_SIZE, GAMMA, len(ACTIONS))
losses.append(loss)
num_of_weight_updates += 1
if (epsilon > EPSILON_END):
epsilon = self.decayEpsilon(epsilon, EPSILON_START, EPSILON_END, FINAL_EXPLORATION_STATE)
if (num_of_weight_updates % TARGET_NETWORK_UPDATE_FREQ == 0) and (num_of_weight_updates != 0): # update weights of target network
Q.update_target_network()
print("Target_network is updated!")
episode_rewards.append(episode_reward)
I have also checked the Q.train_network and Q.update_target_network functions and they work fine.
I was wondering if problem can be in hyper parameters:
ACTIONS = {"NOOP":0,"FIRE":1,"RIGHT":2,"LEFT":3,"RIGHTFIRE":4,"LEFTFIRE":5}
NUM_OF_FRAMES = 4 # number of frames that make 1 state
EPISODES = 10000 # number of episodes
BUFFER_SIZE = 300000 # size of the replay buffer(can not put bigger size, RAM)
MIN_OBSERVATIONS = 30000
RESOLUTION = 84 # resolution of frames
BATCH_SIZE = 32
EPSILON_START = 1 # starting value for the exploration probability
EPSILON_END = 0.1
FINAL_EXPLORATION_STATE = 300000 # final frame for which epsilon is decayed
GAMMA = 0.99 # discount factor
TARGET_NETWORK_UPDATE_FREQ = 10000
REPORT_EPISODE_FREQ = 100
TRAINING_FREQUENCY = 4
OPTIMIZER = RMSprop(lr=0.00025,rho=0.95,epsilon=0.01)

Get a specific data from a json array in erlang using rfc4627

This is the output I get after running following 2 commands.
Wc = os:cmd("curl -s -k -X GET 'http://10.210.12.158:10065/iot/get/task_id?id=1'"),
WW = decode_json(Wc),
OUTPUT ---
{ok,{obj,[{"status",200},
{"data",
[{obj,[{"id",1},
{"task",
<<"Turn on the bulb when the temperature is greater than 28 ">>},
{"working_condition",1},
{"depending_value",<<"Temperature">>},
{"device",<<" BulbOnly">>},
{"turning_point",28},
{"config_id",null}]}]}]}}
I want to get these data separately.
Eg - Task = Turn on the bulb when the temperature is greater than 28
So, How can I do this?
This the structure returned seems to return a list of tasks and each task being a proplist, you can do something like
-module(test).
-export([input/0, get_tasks/1]).
input() ->
{ok,{obj,[{"status",200},
{"data",
[{obj,[{"id",1},
{"task",
<<"Turn on the bulb when the temperature is greater than 28 ">>},
{"working_condition",1},
{"depending_value",<<"Temperature">>},
{"device",<<" BulbOnly">>},
{"turning_point",28},
{"config_id",null}]}]}]}}.
get_tasks({ok, {obj, [_Status, {"data", Tasks}|_Tail]}}) ->
[ get_task_description(T) || T <- Tasks ].
get_task_description({obj, Proplist}) ->
proplists:get_value("task", Proplist).
When running it in a shell, you would get:
1> test:get_tasks(test:input()).
[<<"Turn on the bulb when the temperature is greater than 28 ">>]

Pyevolve - sum of chromosome = 1

# Genome instance, 1D List of 20 elements
genome = G1DList.G1DList(20)
Sets the range max and min of the 1D List
genome.setParams(rangemin=0, rangemax=1)
Change the initializator to Real values
genome.initializator.set(Initializators.G1DListInitializatorReal)
This give 20 elements between 0 and 1. I need that the sum of all elements in the chromosome to be equal to 1 . Any idea how to do this?
I found the answer. I created my own Initializator which is a modified copy of G1DListInitializatorReal:
def G1DListInitializatorRealSumEqualOne(genome, **args):
""" Real initialization function of G1DList
This initializator accepts the *rangemin* and *rangemax* genome parameters.
"""
range_min = genome.getParam("rangemin", 0)
range_max = genome.getParam("rangemax", 100)
genome.genomeList = [random.uniform(range_min, range_max) for i in xrange(genome.getListSize())]
genome.genomeList[:] = [x / sum(genome.genomeList) for x in genome.genomeList]
And then changed the code in my question to:
# Genome instance, 1D List of 20 elements
genome = G1DList.G1DList(20)
Sets the range max and min of the 1D List
genome.setParams(rangemin=0, rangemax=1)
Change the initializator to Real values
genome.initializator.set(G1DListInitializatorRealSumEqualOne)

Converting OBJ data to CSS3D

I found a ton of formulae and what not, but 3D isn't my forte so I'm at a loss of what specifically to use. My goal is to convert the data in an 3D .obj file (vertices, normals, faces) to CSS3D (width, height, rotateX,Y,Z and/or similar transforms).
For example 2 simple planes
g plane1
# simple along along Z axis
v 0.0 0.0 0.0
v 0.0 0.0 1.0
v 0.0 1.0 1.0
v 0.0 1.0 0.0
g plane2
# plane rotated 90 degrees along Y-axis
v 0.0 0.0 0.0
v 0.0 1.0 0.0
v 1.0 1.0 0.0
v 1.0 0.0 0.0
f 1 2 3 4
f 5 6 7 8
Could this data be converted to:
#plane1 {
width: X;
height: Y;
transform: rotateX(Xdeg) rotateY(Ydeg) rotateZ(Zdeg) translateZ(Zpx)
}
#plane2 {
width: X;
height: Y;
transform: rotateX(Xdeg) rotateY(Ydeg) rotateZ(Zdeg) translateZ(Zpx)
}
/* Or something equivalent such as transform: matrix3d() */
The core question is how to get the X/Y/Z-rotation of a 4 point plane from it's matrix of x,y,z coordinates?
UPDATE #1 - 11/12/12
So based on the answers provided, I've come across the unoptimized function from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToEuler/index.htm below:
/*
-v 0.940148 -0.847439 -1.052535
-v 0.940148 -0.847439 0.947465
-v -1.059852 -0.847439 0.947465
-v -1.059852 -0.847439 -1.052535
-v 0.940148 1.152561 -1.052534
-v 0.940147 1.152561 0.947466
-v -1.059852 1.152561 0.947465
v -1.059852 1.152561 -1.052535
f 1 2 3 4
f 5 8 7 6
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 5 1 4 8
*/
var f = {
'm00' : 0.940148,
'm01' : -0.847439,
'm02' : -1.052535,
'm10' : 0.940148,
'm11' : -0.847439,
'm12' : 0.947465,
'm20' : -1.059852,
'm21' : -0.847439,
'm22' : 0.947465
}
// Assuming the angles are in radians.
if (f.m10 > 0.998) { // singularity at north pole
heading = Math.atan2(f.m02, f.m22);
attitude = Math.PI/2;
bank = 0;
} else if (f.m10 < -0.998) { // singularity at south pole
heading = Math.atan2(f.m02,f.m22);
attitude = -Math.PI/2;
bank = 0;
} else {
heading = Math.atan2(-f.m20, f.m00);
bank = Math.atan2(-f.m12, f.m11);
attitude = Math.asin(f.m10);
}
I'm getting results, but I'm not sure if my calculations are correct and I'm also getting mixed responses on what corresponds to which axis. Is it heading = y, bank = x, and attitude = z? I'm also converting each to degrees if that matters.
Read this http://www.songho.ca/opengl/gl_matrix.html It explains pretty much everything and there is implementation.
Beside that the CSS 3D solution will have lower performance(order of magnitude) mainly because each pice of represented surface is DOM element, it's also highly limited - you can find numerous materials about this issue(Google IO records for example)
If you need declarative 3D framework you might want to look at x3dom
To draw a 3D box you just need to include x3dom js script and embed this declaration in your page:
<body>
<h1>Hello X3DOM World</h1>
<x3d width="400" height="300">
<scene>
<shape>
<box></box>
</shape>
</scene>
</x3d>
</body>
It will parse <x3d> tags on your page and generate proper WebGL or Flash implementation with the good performance.
x3d has way to import assets from Blender, Maya and 3ds Max.
Here is some good reading: x3domIntroTutorial.pdf
IE 11 will support WebGL and IE10 will autoupdate to IE 11 so only non-supporting desktop browser(disabled by default) will be Safari. Apple will be forced to enable it by default. With full desktop support it won't take too long to get full mobile because it's highly competitive market. And we have highly accessible WebGL framework like three.js. So there is no sense in doing it with CSS 3D
UPDATE: iOS 8 Safari will enable WebGL support by default: http://caniuse.com/webgl