1
0
Fork 0
pull/7/head
Cees Bassa 2017-11-18 15:12:55 +01:00
commit 3c221de4aa
30 changed files with 1822 additions and 91 deletions

48
README2.md 100644
View File

@ -0,0 +1,48 @@
Satellite Tracking Toolkit
=========
Sattools is a collection of tools to facilitate Photographic and Video satellite tracking.
Install notes
-------------
* Clone locally the code repository
* Install common dependencies
* gfortran
* gcc
* libpng-dev
* libx11-dev
* libjpeg-dev
* libexif-dev
* Build & install required libraries
* qfits-5.2.0: ftp://ftp.eso.org/pub/qfits/qfits-5.2.0.tar.gz
* pgplot-5.2.2: http://www.astro.caltech.edu/~tjp/pgplot/
* gsl-1.15: ftp://ftp.gnu.org/gnu/gsl/gsl-1.15.tar.gz
* wcslib-2.9: http://www.epta.eu.org/~bassa/wcslib-2.9.tar
* Run `make` on the sattools folder
* Helper scripts install_dependencies.sh and install_sattools.sh are available at scripts directory.
You can try run these scripts to install or use them as install guide.
Note that install_dependencies.sh needs to be run with admin privileges (sudo ./install_dependencies.sh).
* If you re-run install_sattools.sh you should previously rmdir sattools directory or otherwise souces
will not be fetched even if they are not present at that dir
Run notes
---------
* You will need to set the following environment variables to run sattools.
These vars are set with default values after running install_sattolls.sh.
`ST_COSPAR` COSPAR number
`ST_DATADIR` path to sattools directory
`ST_TLEDIR` path to TLE directory
`ST_OBSDIR` path to observations directory
* If you have multiple capture devices you will need to add a /etc/udev/rules.d/99-server.rules file to add symlinks and use them to
address a particular camera. Sattools will automatically select the camera that is scheduled for each observation.
You may use a command such as 'udevadm info -a -n /dev/video0' to get your capture device attributes and
use that to create the rules file.
A sample rules file is available as guide in data/
Note that symlinks to the rules file do not work, the rules file must be modified to suit your needs
and copied to /etc/udev/rules.d/
* You should install NTP support on the system and configure time/date to automatically
sinchronize to time servers.
* Modify stget.sh for your space-track.org login and password (--post-data='identity=login&password=password')

View File

@ -0,0 +1,2 @@
KERNEL=="video[0-9]*", ATTR{name}=="Laptop_Integrated_Webcam_1.3M", SYMLINK+="video-Webcam"
KERNEL=="video[0-9]*", ATTR{name}=="AV TO USB2.0", SYMLINK+="video-S25H"

View File

@ -1,5 +1,5 @@
# List of available cameras
# Camera mnemonic (Camera/Optics), field width, field height, horiz resolution (neg.to mirror), vert resolution (neg.to mirror), mount type (AltAz/Eq/XY/Fixed), video device
# Camera mnemonic (Camera/Optics), field width, field height, horiz resolution (neg.to mirror), vert resolution (neg.to mirror), mount type (AltAz/Eq/XY/Fixed), video device , Azimuth (for fixed, south is zero), Altitude (for fixed)
W50H 7.21 5.31 -720 576 AltAz /dev/video1
W28H 13.10 7.97
D85V 9.97 14.96

View File

@ -66,4 +66,4 @@
9003 CP -24.6272 -70.4047 2638 Cerro Paranal
9004 LP 28.7622 -17.8775 2396 Isaac Newton
9999 GR 47.348 5.5151 100 Graves
0531 FM -34.8961 -56.1227 30 Fernando Mederos
0899 FM -34.8961 -56.1227 30 Fernando Mederos

View File

@ -7,11 +7,26 @@
#include "qfits.h"
#include <gsl/gsl_multifit.h>
#include <getopt.h>
#include <time.h>
#define LIM 256
#define D2R M_PI/180.0
#define R2D 180.0/M_PI
#define NMAX 4096
#define MAXPOINTERR 200 // Maximum pointing error (pixels)
// Algorithm will not choose reference stars closer than this amount to any edge (in pixels)
// because matching star may fall outside astrometric field.
// This should change to arcseconds in the future and be used to widen
// the astrometric catalog so that it's scale is grater than that of the imaged catalog just enough
// to be sure it includes all imaged stars even at the worst pointing error.
#define MAXROT 15*D2R // Maximum expected rotation error (radians)
#define MAXSCALERR 1.05 // Expected image to astrometric map scaling error
#define DISTMATCHTOL 6 // Distance tolerance in pixels between matching stars after aplying scale and rotation
#define MAXMAGERR 3 // Expected magnitude error between imaged stars and corresponding astometric catalog stars
#define MAGMATCHTOL 0.75 // Relative magnitude between matching stars tolerance
#define DEFMATCHVALRATIO 0.35 // Default ratio of imaged stars that must fit into astrometric catalog after applying matching transformation (can be adjusted at runtime)
#define AUTOMAGLIM 1 // Automatically set astrometric catalog magnitude limit
#define DEBUG 0
struct star {
double ra,de;
@ -50,6 +65,8 @@ double gmst(double mjd);
double modulo(double x,double y);
void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de);
double sex2dec(char *s);
float matchvalratio=DEFMATCHVALRATIO;
// Read astrometric catalog
struct catalog read_astrometric_catalog(char *filename,float mmin,float sx,float sy,float angle)
@ -65,7 +82,7 @@ struct catalog read_astrometric_catalog(char *filename,float mmin,float sx,float
file=fopen(filename,"rb");
if (file==NULL) {
fprintf(stderr,"%s not found!\n",filename);
fprintf(stdout,"%s not found!\n",filename);
exit(0);
}
while (!feof(file)) {
@ -211,12 +228,12 @@ int match_catalogs(struct catalog *cat,struct catalog *ast,float rmax)
for (i=0,n=0;i<cat->n;i++) {
for (j=0,flag=0;j<ast->n;j++) {
if (ast->select[j]!=0)
continue;
continue;
r=sqrt(pow(cat->x[i]-ast->x[j],2)+pow(cat->y[i]-ast->y[j],2));
if (flag==0 || r<rmin) {
rmin=r;
jmin=j;
flag=1;
rmin=r;
jmin=j;
flag=1;
}
}
if (rmin<rmax) {
@ -280,6 +297,598 @@ void get_site(int site_id)
return;
}
// Identify matching triangles in imaged and astrometric catalogs
void identify_triangles(struct catalog *cat, struct catalog *ast, int *nselect, int tricat[3], int triast[3])
{
float r,d,d2,x,y;
float mag12,mag13,mag23,ang12,ang13,dis12,dis13,dis23,cenX,cenY;
float mmax,mmin,matchscale,matchrot,matchXtras,matchYtras;
float error=MAXPOINTERR; // maximum expected pointing error in pixels
int i,j,n,n2,s1,s2,s3,m1,m2,m3;
static int nmatch;
clock_t start_t, end_t;
static float mave,size;
start_t=clock();
// Form a triangle of reference stars from imaged catalog. The following criteria is used:
// Triangle should cover as much area of FOV as possible.
// Cannot choose stars too near edges because they may fall outside of astrometric catalog
// 1st star will be chosen with lower than average magnitude and separated from any edge as
// much as estimated pointing error. Estimated error is given in pixels for now.
// 2nd and 3rd stars will also be chosen with lower than average magnitude.
//
// Acceptable minimum distance from stars in triangle is set as image width minus pointing error
// In the future min distance between stars and estimated pointing error should be given in arcsecs and converted
// to pixels
// if a reference triangle match was already found, we want to find another one, so we don't start
// from zero
if((triast[0]!=0) || (triast[1]!=0) || (triast[2]!=0)){
// this time search for another match beginning with the following 3rd star
triast[2]++;
#if DEBUG>0
fprintf(stdout,"Try different match.\n");
#endif
}
else{
// Either no match was found or this is the first time the routine is launched so
// we calculate reference triangle parameters...
// size=(img.naxis2-error)/2;
size=(img.naxis2-error)/3;
// Compute magnitude average
mave=0;
mmax=0;
mmin=10;
for (i=0;i<cat->n;i++) {
r=cat->mag[i];
if(r > mmax)
mmax=r;
if(r < mmin)
mmin=r;
mave+=r;
}
mave/=cat->n;
#if DEBUG>2
fprintf(stdout,"Image height: %d, Expected error: %f, Ref.Tria.Size: %f\n",img.naxis2,error,size);
#endif
if(size<0){
fprintf(stdout,"Warning: Pointing inaccuracy too high\n");
size=10;
}
#if DEBUG>0
fprintf(stdout,"Stars in imaged catalog: %d, stars in astrometric catalog: %d.\n", cat->n, ast->n);
fprintf(stdout,"MMin:%2.1f,MMax:%2.1f,MAve.:%2.1f \n",mmin,mmax,mave);
#endif
triast[0]=0;
triast[1]=0;
triast[2]=0;
#if DEBUG>2
fprintf(stdout,"Try different triangle. Size: %f\n",size);
#endif
}
*nselect=0;
nmatch=0;
// search for candidate triangles satisfying size minimum and stars magnitude, later we can fall back to smaller size if no suitable triangle
// is found
// while((*nselect<3) && (size > 10)){
while((nmatch<3) && (size > 10)){
// *nselect=0;
#if DEBUG>1
fprintf(stdout,"Looking for triangles with min size %4.0f\n",size);
#endif
// Search candidate for 1st star
for(s1=tricat[0];(nmatch<3) && (s1 <= cat->n);s1++){
// discard if outside high magnitude range
r=cat->mag[s1];
if(r > mave){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for high magnitude.\n",s1);
#endif
continue;
}
// discard if too close to any edge
if((cat->x[s1] < error/2) || (cat->x[s1] > (img.naxis1-error/2))){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to edge.\n",s1);
#endif
continue;
}
if((cat->y[s1] < error/2) || (cat->y[s1] > (img.naxis2-error/2))){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to edge.\n",s1);
#endif
continue;
}
// s1 is viable candidate for 1st star
#if DEBUG>1
fprintf(stdout,"Candidate star 1: %d, magnitude: %.1f \n",s1,r);
#endif
tricat[0]=s1;
*nselect=1;
#if DEBUG>1
fprintf(stdout,"Looking for 2nd star of triangle.\n");
#endif
// Search candidate for 2nd star
for(s2=tricat[1];(nmatch<3) && (s2 <= cat->n);s2++){
// discard candidate if outside magnitude range
r=cat->mag[s2];
if(r > mave){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for high magnitude.\n",s2);
#endif
continue;
}
// discard if too close to any edge
if((cat->x[s2] < error/2) || (cat->x[s2] > (img.naxis1-error/2))){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to edge.\n",s2);
#endif
continue;
}
if((cat->y[s2] < error/2) || (cat->y[s2] > (img.naxis2-error/2))){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to edge.\n",s2);
#endif
continue;
}
// discard if too close to star 1
r=sqrt(pow(cat->x[s2]-cat->x[s1],2)+pow(cat->y[s2]-cat->y[s1],2));
if(r < size){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to 1st star.\n",s2);
#endif
continue;
}
// s2 is viable candidate for 2nd star
#if DEBUG>1
fprintf(stdout,"Candidate star 2: %d, magnitude: %.1f, distance to star 1: %.1f \n",s2,cat->mag[s2],r);
#endif
tricat[1]=s2;
*nselect=2;
#if DEBUG>1
fprintf(stdout,"Looking for 3rd star of triangle.\n");
#endif
// Search candidate for 3rd star beginning from the last candidate found
for(s3=tricat[2];(nmatch<3) && (s3 <= cat->n);s3++){
// discard candidate if outside magnitude range
r=cat->mag[s3];
if(r > mave){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for high magnitude.\n",s3);
#endif
continue;
}
// discard if too close to any edge
if((cat->x[s3] < error/2) || (cat->x[s3] > (img.naxis1-error/2))){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to edge.\n",s3);
#endif
continue;
}
if((cat->y[s3] < error/2) || (cat->y[s3] > (img.naxis2-error/2))){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to edge.\n",s3);
#endif
continue;
}
// discard if too close to star 1
r=sqrt(pow(cat->x[s3]-cat->x[s1],2)+pow(cat->y[s3]-cat->y[s1],2));
if(r < size){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to 1st star.\n",s3);
#endif
continue;
}
// discard if too close to star 2
r=sqrt(pow(cat->x[s3]-cat->x[s2],2)+pow(cat->y[s3]-cat->y[s2],2));
if(r < size){
#if DEBUG>2
fprintf(stdout,"Star %d discarded for close to 2nd star.\n",s3);
#endif
continue;
}
// s3 is viable candidate for 3rd star
#if DEBUG>1
fprintf(stdout,"Candidate star 3: %d, magnitude: %.1f, distance to star 2: %.1f \n",s3,cat->mag[s3],r);
#endif
#if DEBUG>1
fprintf(stdout,"\n");
fprintf(stdout,"Reference triangle: %d, %d, %d\n",s1,s2,s3);
fprintf(stdout,"Magnitudes: %f, %f, %f\n",cat->mag[s1],cat->mag[s2],cat->mag[s3]);
#endif
tricat[2]=s3;
*nselect=3;
// ************************************************************
// Calibration triangle candidate found!
// now look for matching triangle in astrometric catalog...
// ************************************************************
// at this point we have got 3 reference stars forming suitable triangle, will look for matching triangle in astrometric catalog
// will search by testing relative magnitude and relative distance between suspect matching stars
// a scale tolerance is given as a ratio for distances (triangle size) and is assumed as affecting the whole image,
// this tolerance could be high.
// Also a magnitude tolerance is defined as an absolute value, this should not be too high (1..2 magnitudes)
//
// relative distance between stars of astrometric catalog should closely match relative distances between stars of imaged catalog
// a tolerance for this match is given also as a ratio and should be low
// also magnitude difference between stars of matching triangle should closely match magn diff between stars of imaged
// reference triangle, tolerance for this magnitude match should not be high (0.5 magn or so)
nmatch=0;
// Search for candidate 1st match star
for(m1=triast[0];((nmatch<3) && (m1<=ast->n));m1++){
// discard if outside magnitude tolerance
// this tolerance includes magnitude extraction tolerance on sextractor tool
r=fabs(cat->mag[s1] - ast->mag[m1]);
if(r > MAXMAGERR){
#if DEBUG>2
fprintf(stdout,"Match 1st star %d discarded for mag. difference.\n",m1);
#endif
continue;
}
r=ast->mag[m1];
// m1 is viable candidate for match to 1st reference star
#if DEBUG>1
fprintf(stdout,"Candidate match star 1: %d, magnitude: %.1f \n",m1,r);
#endif
triast[0]=m1;
nmatch=1;
// Calculate some values that will be repeatedly used during match check loop
mag12=cat->mag[s2] - cat->mag[s1];
dis12=sqrt(pow(cat->x[s2]-cat->x[s1],2)+pow(cat->y[s2]-cat->y[s1],2));
ang12=atan((cat->y[s2]-cat->y[s1]) / (cat->x[s2]-cat->x[s1]));
if((cat->x[s2]-cat->x[s1]) < 0){
if(ang12 >= 0) ang12 -= M_PI;
else ang12 += M_PI;
}
// Search candidate for 2nd star
for(m2=triast[1];(nmatch<3) && (m2<=ast->n);m2++){
// magn difference between ref stars 1 and 2 should be very close to magn diff between matching stars 1 and 2
// discard if difference is outside match tolerance
if(fabs(mag12 - (ast->mag[m2] - ast->mag[m1])) > MAGMATCHTOL){
#if DEBUG>2
fprintf(stdout,"Match 2nd star %d discarded for mag. match tolerance.\n",m2);
#endif
continue;
}
// distance between ref stars 1 and 2 should resemble distance from matching stars 1 and star 2 allowing for
// scale tolerance
d=sqrt(pow(ast->x[m2]-ast->x[m1],2)+pow(ast->y[m2]-ast->y[m1],2)) / dis12;
// discard if distance between m2 and m1 is too far from distance between s2 and s1
if((d > MAXSCALERR) || (1/d > MAXSCALERR)){
#if DEBUG>2
fprintf(stdout,"Match 2nd star %d discarded for distance to 1st match star error.\n",m2);
#endif
continue;
}
// keep scale to later check for coherence with third matching star
// this scale was obtained from distance ratio between ref stars 1 & 2 and match stars 1 & 2
matchscale=d;
#if DEBUG>1
fprintf(stdout,"Triangle size match scale: %f.2.\n",matchscale);
#endif
// check angle
d2=atan((ast->y[m2]-ast->y[m1]) / (ast->x[m2]-ast->x[m1]));
if((ast->x[m2]-ast->x[m1]) < 0){
if(d2 >= 0) d2 -= M_PI;
else d2 += M_PI;
}
if(fabs(d2 - ang12) > MAXROT){
#if DEBUG>2
fprintf(stdout,"Match 2nd star %d discarded for rotation error.\n",m2);
#endif
continue;
}
// keep rotation for later checks
// this rotation was obtained from angle between ref stars 1 & 2 and match stars 1 & 2
matchrot=d2-d;
// m2 is viable candidate for match to 2nd star
r=ast->mag[m2];
#if DEBUG>1
fprintf(stdout,"Candidate match star 2: %d, magnitude: %.1f \n",m2,r);
#endif
#if DEBUG>2
fprintf(stdout,"Angle star 1 to star 2: %f \n",d);
d2=atan((ast->y[m2]-ast->y[m1]) / (ast->x[m2]-ast->x[m1]));
fprintf(stdout,"Angle match 1 to match 2: %f \n",d2);
d=fabs(d - d2);
fprintf(stdout,"Angle error %f \n",d);
#endif
triast[1]=m2;
nmatch=2;
// calculate values that will be used repeatedly
mag13=cat->mag[s3] - cat->mag[s1];
mag23=cat->mag[s3] - cat->mag[s2];
cenX=(cat->x[s1] + cat->x[s2] + cat->x[s3]) / 3;
cenY=(cat->y[s1] + cat->y[s2] + cat->y[s3]) / 3;
dis13=matchscale * sqrt(pow(cat->x[s3]-cat->x[s1],2)+pow(cat->y[s3]-cat->y[s1],2));
dis23=matchscale * sqrt(pow(cat->x[s3]-cat->x[s2],2)+pow(cat->y[s3]-cat->y[s2],2));
ang13=atan((cat->y[s3]-cat->y[s1]) / (cat->x[s3]-cat->x[s1]));
if((cat->x[s3]-cat->x[s1]) < 0){
if(ang13 >= 0) ang13 -= M_PI;
else ang13 += M_PI;
}
// Search candidate for 3rd star
for(m3=triast[2];(nmatch<3) && (m3<=ast->n);m3++){
// discard if magn difference is outside match tolerance
if(fabs(mag13 - (ast->mag[m3] - ast->mag[m1])) > MAGMATCHTOL){
#if DEBUG>2
fprintf(stdout,"Match 3rd star %d discarded for mag. match tolerance.\n",m3);
#endif
continue;
}
if(fabs(mag23 - (ast->mag[m3] - ast->mag[m2])) > MAGMATCHTOL){
#if DEBUG>2
fprintf(stdout,"Match 3rd star %d discarded for mag. match tolerance.\n",m3);
#endif
continue;
}
// discard this star if matching triangle center is too far from reference triangle center
// check pointing error along X axis
d=(ast->x[m1] + ast->x[m2] + ast->x[m3]) / 3;
if((d2=fabs(d - cenX)) > error){
#if DEBUG>2
fprintf(stdout,"Match 3rd star %d discarded for excesive X pointing error: %f.\n",m3,d2);
#endif
continue;
}
// check pointing error along Y axis
d=(ast->y[m1] + ast->y[m2] + ast->y[m3]) / 3;
if((d2=fabs(d - cenY)) > error){
#if DEBUG>2
fprintf(stdout,"Match 3rd star %d discarded for excesive Y pointing error: %f.\n",m3,d2);
#endif
continue;
}
// scale was fixed when found 2nd match candidate, no different scale error is allowed for 3rd matching star
// discard if distance between m3 and m1 is not very similar to distance between s3 and s1
d=sqrt(pow(ast->x[m3]-ast->x[m1],2)+pow(ast->y[m3]-ast->y[m1],2));
if(fabs(d - dis13) > DISTMATCHTOL){
#if DEBUG>2
fprintf(stdout,"Match 3rd star %d discarded for distance to 1st match star error: %f against %f.\n",m3,r,d);
#endif
continue;
}
// discard if distance between m3 and m2 is not very similar to distance between s3 and s2
if(fabs(sqrt(pow(ast->x[m3]-ast->x[m2],2)+pow(ast->y[m3]-ast->y[m2],2)) - dis23) > DISTMATCHTOL){
#if DEBUG>2
fprintf(stdout,"Match 3rd star %d discarded for distance to 2nd match star error.\n",m3);
#endif
continue;
}
// check angle
d2=atan((ast->y[m3]-ast->y[m1]) / (ast->x[m3]-ast->x[m1]));
if((ast->x[m3]-ast->x[m1]) < 0){
if(d2 >= 0) d2 -= M_PI;
else d2 += M_PI;
}
if(fabs(d2 - ang13) > MAXROT){
#if DEBUG>2
fprintf(stdout,"Match 3rd star %d discarded for rotation error.\n",m3);
#endif
continue;
}
// m3 is viable candidate for match to 3rd star
r=ast->mag[m3];
#if DEBUG>1
fprintf(stdout,"Match found with 3rd match star: %d, magnitude: %.1f \n",m3,r);
#endif
#if DEBUG>0
fprintf(stdout,"Reference triangle: %d, %d, %d\n",s1,s2,s3);
fprintf(stdout,"Match found with stars: %d, %d, %d\n",m1,m2,m3);
#endif
triast[2]=m3;
// ************************************************************************************************************
// At this point a viable candidate triangle is found to match the selected reference triangle
// will try to validate this candidate by calculating the tranformation between the ref triangle and this candidate
// We will need to calculate scale, rotation and traslation
end_t=clock();
#if DEBUG>1
fprintf(stdout,"\n");
fprintf(stdout,"Match triangle found: %d,%d,%d\n",m1,m2,m3);
fprintf(stdout,"Magnitudes: %f, %f, %f\n",ast->mag[m1],ast->mag[m2],ast->mag[m3]);
fprintf(stdout,"Reference triangle: %d, %d, %d\n",s1,s2,s3);
fprintf(stdout,"Magnitudes: %f, %f, %f\n",cat->mag[s1],cat->mag[s2],cat->mag[s3]);
d=(float)(end_t - start_t)/CLOCKS_PER_SEC;
fprintf(stdout,"Seconds elapsed: %f\n",d);
#endif
start_t=clock();
// Scale transformation calculation
// scaling from ref 1-2 to match 1-2 was previously calculated in matchscale, now we average with
// ref 2-3 to match 2-3 and ref 3-1 to match 3-1
r=sqrt(pow(cat->x[s3]-cat->x[s2],2)+pow(cat->y[s3]-cat->y[s2],2));
d=sqrt(pow(ast->x[m3]-ast->x[m2],2)+pow(ast->y[m3]-ast->y[m2],2)) / r;
matchscale += d;
r=sqrt(pow(cat->x[s1]-cat->x[s3],2)+pow(cat->y[s1]-cat->y[s3],2));
d=sqrt(pow(ast->x[m1]-ast->x[m3],2)+pow(ast->y[m1]-ast->y[m3],2)) / r;
matchscale += d;
matchscale /= 3;
// Rotation calculation
// matchrot was obtained from angle between ref stars 1-2 and match stars 1-2
// now average with angle ref 2-3 to match 2-3 and angle ref 3-1 to match 3-1
d2=atan((ast->y[m2]-ast->y[m1]) / (ast->x[m2]-ast->x[m1]));
if((ast->x[m2]-ast->x[m1]) < 0){
if(d2 >= 0) d2 -= M_PI;
else d2 += M_PI;
}
matchrot = d2-ang12;
d=atan((cat->y[s3]-cat->y[s2]) / (cat->x[s3]-cat->x[s2]));
if((cat->x[s3]-cat->x[s2]) < 0){
if(d >= 0) d -= M_PI;
else d += M_PI;
}
d2=atan((ast->y[m3]-ast->y[m2]) / (ast->x[m3]-ast->x[m2]));
if((ast->x[m3]-ast->x[m2]) < 0){
if(d2 >= 0) d2 -= M_PI;
else d2 += M_PI;
}
matchrot += d2-d;
d=atan((cat->y[s1]-cat->y[s3]) / (cat->x[s1]-cat->x[s3]));
if((cat->x[s1]-cat->x[s3]) < 0){
if(d >= 0) d -= M_PI;
else d += M_PI;
}
d2=atan((ast->y[m1]-ast->y[m3]) / (ast->x[m1]-ast->x[m3]));
if((ast->x[m1]-ast->x[m3]) < 0){
if(d2 >= 0) d2 -= M_PI;
else d2 += M_PI;
}
matchrot += d2-d;
matchrot /= 3;
// traslation calculation
// we apply averaged matchscale and matchrotation to reference stars and then
// average reference1 to match1 vector, ref2 to match2 vector and ref3 to match3 vector
r=sqrt(pow(cat->x[s1],2)+pow(cat->y[s1],2));
d=atan(cat->y[s1] / cat->x[s1]);
r *= matchscale;
d += matchrot;
matchXtras = ast->x[m1] - r*cos(d);
matchYtras = ast->y[m1] - r*sin(d);
r=sqrt(pow(cat->x[s2],2)+pow(cat->y[s2],2));
d=atan(cat->y[s2] / cat->x[s2]);
r *= matchscale;
d += matchrot;
matchXtras += ast->x[m2] - r*cos(d);
matchYtras += ast->y[m2] - r*sin(d);
r=sqrt(pow(cat->x[s3],2)+pow(cat->y[s3],2));
d=atan(cat->y[s3] / cat->x[s3]);
r *= matchscale;
d += matchrot;
matchXtras += ast->x[m3] - r*cos(d);
matchYtras += ast->y[m3] - r*sin(d);
matchXtras /= 3;
matchYtras /= 3;
#if DEBUG>1
fprintf(stdout,"Transformation:\nScale: %f\nRotation: %f\nXTraslat: %f\nYTraslat: %f\n",matchscale,matchrot,matchXtras,matchYtras);
#endif
// At this point we've determined the transformation function to convert our reference triangle in the image
// to a matching triangle in the astrometric catalog
// Now it's time to check if this tranformation effectively maps our imaged stars catalog into the astrometric catalog
// For this we apply the tranformation to every bright star in the imaged catalog and accumulate success count when
// a matching star is found in the astrometric catalog. This count is later used for validation.
n=0;
n2=0;
// d2=(mmin+mave)/2;
// d2=(mmax+mave)/2;
d2=mave;
for(i=0;i<=cat->n;i++){
// skip faint stars from the match check
if(cat->mag[i] > d2) continue;
r=sqrt(pow(cat->x[i],2)+pow(cat->y[i],2));
d=atan(cat->y[i] / cat->x[i]);
r *= matchscale;
d += matchrot;
x=r*cos(d) + matchXtras;
y=r*sin(d) + matchYtras;
n2++; // this star counts as a checked star
for(j=0;j<=ast->n;j++){
// skip also faint stars from map
if(ast->mag[j] > (d2 + MAXMAGERR)) continue;
if((fabs(ast->x[j] - x) < DISTMATCHTOL) && (fabs(ast->y[j] - y) < DISTMATCHTOL)){
n++;
break;
}
}
}
if(n < n2*matchvalratio){
#if DEBUG>0
fprintf(stdout,"Match discarded for insufficient match number: %d out of %d checked stars\n",n,n2);
#endif
// if(m1==101 && m2==80 && m3==87){
// end_t=clock();
// fprintf(stdout,"Special match triangle was discarded, halting...\n");
// nmatch=3;
// }
continue;
}
fprintf(stdout,"Match count: %d out of %d checked stars\n",n,n2);
nmatch=3;
}
// if no match found next try will search again for all possible 3rd match stars
if(nmatch<3) triast[2]=0;
}
// if no match found next try will search again for all possible 2nd match stars
if(nmatch<3) triast[1]=0;
}
if(nmatch<3){
triast[0]=0;
// if no match was found for this ref triangle continue looking for ref triangles
// next try with following 3rd star
*nselect=2;
#if DEBUG>1
fprintf(stdout,"No match found for this triangle\n");
#endif
}
}
// if no triangle selected we will try next 2nd star and try again all possible 3rd stars
if(nmatch<3){
tricat[2]=0;
*nselect=1;
#if DEBUG>2
fprintf(stdout,"Try next 3rd star.\n");
#endif
}
}
// if no triangle selected we will try next 1st star and try again all possible 2nd stars
if(nmatch<3){
tricat[1]=0;
*nselect=0;
#if DEBUG>2
fprintf(stdout,"Try next 2nd star.\n");
#endif
}
}
// at this point either found 3 candidate stars or already tried all candidate stars without success
// if loop continues will look for smaller triangles, accept higher magnitude stars and
// accept lower match ratio for next iteration
if(nmatch<3){
size/=1.25;
mave+=0.25;
// relax match constraint
matchvalratio/=1.25;
tricat[0]=0;
#if DEBUG>0
fprintf(stdout,"Catalog completely parsed with no suitable reference triangle found. Decrasing minimum size, increase max magnitude for next search.\n");
#endif
}
}
// if we could not find suitable triplet erase triange in catalog tricat[]
if(nmatch<3){
tricat[0]=0;
tricat[1]=0;
tricat[2]=0;
#if DEBUG>0
fprintf(stdout,"Did not find any suitable reference triangle.\n");
#endif
}
return;
}
int main(int argc,char *argv[])
{
int i;
@ -298,6 +907,7 @@ int main(int argc,char *argv[])
int nx,ny;
FILE *file;
char *env,starfile[128];
int tricat[3],triast[3],n;
// Environment variables
env=getenv("ST_DATADIR");
@ -324,7 +934,7 @@ int main(int argc,char *argv[])
} else {
file=fopen("position.txt","r");
if (file==NULL) {
fprintf(stderr,"No position file found\n");
fprintf(stdout,"No position file found\n");
return 0;
}
fscanf(file,"%s %s",sra,sde);
@ -344,17 +954,17 @@ int main(int argc,char *argv[])
if (file==NULL) {
sx=-36.15;
sy=33.22;
fprintf(stderr,"No camera file found, using default pixel scale values %3.2f %3.2f\n",sx,sy);
fprintf(stdout,"No camera file found, using default pixel scale values %3.2f %3.2f\n",sx,sy);
}
else{
// Obtain FOV and image resolution from camera file
fscanf(file,"%s %f %f %d %d %s",cam,&fw,&fh,&nx,&ny,mount);
fscanf(file,"%s %f %f %d %d %s",cam,&fh,&fw,&nx,&ny,mount);
fclose(file);
sx=fw/nx*3600;
sy=fh/ny*3600;
// Check scheduled camera resolution against FITS image file resolution
if((abs(nx)!=img.naxis1) || (abs(ny)!=img.naxis2)){
fprintf(stderr,"Warning: scheduled camera resolution %dx%d does not match image resolution %dx%d",nx,ny,img.naxis1,img.naxis2);
fprintf(stdout,"Warning: scheduled camera resolution %dx%d does not match image resolution %dx%d\n",nx,ny,img.naxis1,img.naxis2);
}
}
@ -365,6 +975,20 @@ int main(int argc,char *argv[])
// Read catalogs
cat=read_pixel_catalog(filename);
ast=read_astrometric_catalog(starfile,mag,sx,sy,-q);
// Adjust magnitude limit if configured for so
if (AUTOMAGLIM){
while (ast.n > cat.n){
mag -= 0.5;
ast=read_astrometric_catalog(starfile,mag,sx,sy,-q);
}
while (ast.n < cat.n){
mag += 0.25;
ast=read_astrometric_catalog(starfile,mag,sx,sy,-q);
}
fprintf(stdout,"Astrometric map magnitude limit: %2.2f\n",mag);
fprintf(stdout,"Stars in map: %d, extracted imaged stars: %d\n",ast.n,cat.n);
}
// Open PGPlot server
cpgopen("/xs");
@ -395,26 +1019,65 @@ int main(int argc,char *argv[])
cpgctab (heat_l,heat_r,heat_g,heat_b,5,1.0,0.5);
cpgimag(img.z,img.naxis1,img.naxis2,1,img.naxis1,1,img.naxis2,img.zmin,img.zmax,tr);
cpgbox("BCTSNI",0.,0,"BCTSNI",0.,0);
// Plot triangle of calibration stars
if(nselect>=2){
// imaged catalog
cpgmove(cat.x[tricat[0]],cat.y[tricat[0]]);
#if DEBUG>1
fprintf(stdout,"\nRef.triangle: ");
fprintf(stdout,"%d, ",tricat[0]);
#endif
for(i=1;(i<3 && i<nselect);i++){
cpgdraw(cat.x[tricat[i]],cat.y[tricat[i]]);
#if DEBUG>1
fprintf(stdout,"%d, ",tricat[i]);
#endif
}
cpgdraw(cat.x[tricat[0]],cat.y[tricat[0]]);
// astrometric catalog
if(triast[2]>0){
cpgmove(ast.x[triast[0]],ast.y[triast[0]]);
#if DEBUG>1
fprintf(stdout,"\nMatch triangle: ");
fprintf(stdout,"%d, ",triast[0]);
#endif
for(i=1;(i<3 && i<nselect);i++){
cpgdraw(ast.x[triast[i]],ast.y[triast[i]]);
#if DEBUG>1
fprintf(stdout,"%d, ",triast[i]);
#endif
}
cpgdraw(ast.x[triast[0]],ast.y[triast[0]]);
}
}
fflush(stdout);
// Plot catalogs
if (plotstars==1) {
cpgsci(3);
for (i=0;i<cat.n;i++) {
if (cat.select[i]!=0)
cpgpt1(cat.x[i],cat.y[i],6);
else
cpgpt1(cat.x[i],cat.y[i],4);
}
cpgsci(3);
for (i=0;i<cat.n;i++) {
r=rmax-(rmax-rmin)*(cat.mag[i]-mmin)/(mmax-mmin);
r*=img.naxis1/752.0;
//r*=0.1;
if ((n=cat.select[i])!=0){
cpgpt1(cat.x[i],cat.y[i],0);
}
//else
//cpgpt1(cat.x[i],cat.y[i],4);
cpgcirc(cat.x[i],cat.y[i],r);
}
}
cpgsci(4);
for (i=0;i<ast.n;i++) {
r=rmax-(rmax-rmin)*(ast.mag[i]-mmin)/(mmax-mmin);
// Upscale for image size
r*=img.naxis1/752.0;
if (ast.select[i]!=0)
cpgpt1(ast.x[i],ast.y[i],6);
cpgcirc(ast.x[i],ast.y[i],r);
r=rmax-(rmax-rmin)*(ast.mag[i]-mmin)/(mmax-mmin);
// Upscale for image size
r*=img.naxis1/752.0;
if (ast.select[i]!=0)
cpgpt1(ast.x[i],ast.y[i],0);
cpgcirc(ast.x[i],ast.y[i],r);
}
cpgsci(1);
redraw=0;
@ -430,19 +1093,52 @@ int main(int argc,char *argv[])
if (c=='f' && nselect>=3) {
fit_transformation(cat,ast,nselect);
ast=reread_astrometric_catalog(starfile,mag+1);
for (i=0;i<cat.n;i++) {
cat.select[i]=0;
}
for (i=0;i<ast.n;i++) {
ast.select[i]=0;
}
nselect=0;
redraw=1;
}
// Reread
if (c=='R') {
ast=reread_astrometric_catalog(starfile,mag+1);
for (i=0;i<cat.n;i++) {
cat.select[i]=0;
}
for (i=0;i<ast.n;i++) {
ast.select[i]=0;
}
// for(i=0;i<3;i++){
// tricat[i]=0;
// triast[i]=0;
// img.a[i]=0;
// img.b[i]=0;
// }
// triast[2]=-1;
ast=read_astrometric_catalog(starfile,mag,sx,sy,-q);
//ast=reread_astrometric_catalog(starfile,mag);
matchvalratio=DEFMATCHVALRATIO;
tricat[0]=0;
tricat[1]=0;
tricat[2]=0;
triast[0]=0;
triast[1]=0;
triast[2]=0;
redraw=1;
nselect=0;
}
// Select pixel catalog
if (c=='a' && click==0) {
i=select_nearest(cat,x,y);
fprintf(stdout,"%d\n",i);
cat.select[i]=nselect+1;
if(nselect<4)
tricat[nselect]=i;
redraw=1;
click=1;
}
@ -450,24 +1146,75 @@ int main(int argc,char *argv[])
// Select catalog
if (c=='b' && click==1) {
i=select_nearest(ast,x,y);
fprintf(stdout,"%d\n",i);
ast.select[i]=nselect+1;
if(nselect<4)
triast[nselect]=i;
redraw=1;
click=0;
nselect++;
}
// Select pixel catalog
if (c=='1') {
i=select_nearest(cat,x,y);
fprintf(stdout,"Imaged star %d, Mag. %f\n",i,cat.mag[i]);
}
// Select catalog
if (c=='2') {
i=select_nearest(ast,x,y);
fprintf(stdout,"Asto.Catalog star %d, Mag. %f\n",i,ast.mag[i]);
}
// Autoidentify triangles in imaged and astrometric catalogs
if (c=='i') {
ast=read_astrometric_catalog(starfile,mag,sx,sy,-q);
identify_triangles(&cat,&ast,&nselect,tricat,triast);
// if match was found mark stars into selected fields of catalogs
if((nselect >=3) && (triast[2] > 0)){
// erase prior selection first
for (i=0;i<cat.n;i++) {
cat.select[i]=0;
}
for (i=0;i<ast.n;i++) {
ast.select[i]=0;
}
cat.select[tricat[0]]=1;
cat.select[tricat[1]]=2;
cat.select[tricat[2]]=3;
ast.select[triast[0]]=1;
ast.select[triast[1]]=2;
ast.select[triast[2]]=3;
nselect=3;
}
redraw=1;
}
// Reset reference stars selection
if (c=='I' && nselect>=3) {
tricat[0]=0;
triast[0]=0;
tricat[1]=0;
triast[1]=0;
tricat[2]=0;
triast[2]=-1;
nselect=0;
redraw=1;
}
// Plot identified stars
if (c=='p') {
if (plotstars==1)
plotstars=0;
plotstars=0;
else if (plotstars==0)
plotstars=1;
plotstars=1;
redraw=1;
}
// Match catalogs
if (c=='m') {
nselect=match_catalogs(&cat,&ast,10.0);
match_catalogs(&cat,&ast,10.0);
redraw=1;
}
@ -493,7 +1240,7 @@ int main(int argc,char *argv[])
}
// Zoom
if (c=='z' || c=='+' || c=='=') {
if (c=='z') {
width/=1.25;
xmin=x-0.5*width;
xmax=x+0.5*width;
@ -504,7 +1251,7 @@ int main(int argc,char *argv[])
}
// Unzoom
if (c=='x' || c=='-') {
if (c=='x') {
width*=1.25;
xmin=x-0.5*width;
xmax=x+0.5*width;
@ -514,21 +1261,46 @@ int main(int argc,char *argv[])
continue;
}
// More astrometric map stars
if (c=='+' || c=='=') {
mag += 0.25;
fprintf(stdout,"Astrometric map magnitude limit: %2.2f\n",mag);
ast=read_astrometric_catalog(starfile,mag,sx,sy,-q);
fprintf(stdout,"Stars in map: %d, extracted imaged stars: %d\n",ast.n,cat.n);
redraw=1;
continue;
}
// Less astrometric map stars
if (c=='-') {
mag -= 0.25;
fprintf(stdout,"Astrometric map magnitude limit: %2.2f\n",mag);
ast=read_astrometric_catalog(starfile,mag,sx,sy,-q);
fprintf(stdout,"Stars in map: %d, extracted imaged stars: %d\n",ast.n,cat.n);
redraw=1;
continue;
}
// Help
if (c=='h') {
printf("Calibrates astrometry. Initially requires manual matching of at least three stars. Use 'a' to select star on the image, then 'b' to select star from the catalog, then 'f' to fit");
printf("Calibrates astrometry.\nRequires matching of at least three stars. Use 'i' repeatedly for automatic selection of matching sets or 'a' to manually select a star from the image and 'b' to select the corresponding star from the catalog (tree sets needed). Then use 'f' to check fit, 'R' to start again.\nFinish with 'm' to match stars and 'q' writes calibration output\n");
printf("q Quit\n");
printf("a Select star on image\n");
printf("b Select star from catalog\n");
printf("i Autoselect calibration stars from catalog\n");
printf("I Reset calibration stars selection\n");
printf("S Save calibration params. to cal.dat\n");
printf("c Center image on pixel\n");
printf("f Fit calibration\n");
printf("m Match stars using current calibration\n");
printf("z/+ Zoom in on cursor\n");
printf("x/- Zoom out on cursor\n");
printf("z/x Zoom in/out on cursor\n");
printf("+/- Increase/decrease astrometric map stars\n");
printf("p Plot sextractor catalog\n");
printf("r Reset zoom\n");
printf("R Reset fit\n");
}
redraw=1;
continue;
}
cpgend();
@ -731,7 +1503,7 @@ struct catalog read_pixel_catalog(char *filename)
// Read catalog
file=fopen(filename,"r");
if (file==NULL) {
fprintf(stderr,"%s not found!\n",filename);
fprintf(stdout,"%s not found!\n",filename);
exit(0);
}
while (fgetline(file,line,LIM)>0) {

34
pnmenc.patch 100644
View File

@ -0,0 +1,34 @@
--- pnmenc.c 2015-10-23 19:20:02.000000000 +0200
+++ good_pnmenc.c 2017-11-17 21:26:31.638503445 +0100
@@ -23,6 +23,8 @@
#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "internal.h"
+#include <time.h>
+#include <sys/time.h>
static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *p, int *got_packet)
@@ -32,7 +34,13 @@
uint8_t *ptr, *ptr1, *ptr2;
int size = av_image_get_buffer_size(avctx->pix_fmt,
avctx->width, avctx->height, 1);
+ struct timeval tv;
+ char tbuf[30];
+ // Get time
+ gettimeofday(&tv,NULL);
+ strftime(tbuf,30,"%Y-%m-%dT%T",gmtime(&tv.tv_sec));
+
if ((ret = ff_alloc_packet2(avctx, pkt, size + 200, 0)) < 0)
return ret;
@@ -81,7 +89,7 @@
return -1;
}
snprintf(bytestream, bytestream_end - bytestream,
- "P%c\n%d %d\n", c, avctx->width, h1);
+ "P%c\n# %s.%03ld\n%d %d\n", c, tbuf, tv.tv_usec/1000, avctx->width, h1);
bytestream += strlen(bytestream);
if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) {
int maxdepth = (1 << av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth) - 1;

75
python/capture.py 100644
View File

@ -0,0 +1,75 @@
#!/usr/bin/env python
import numpy as np
import cv2
import time
import subprocess
import os
# Make directory
if not os.path.exists("/dev/shm/video0"):
os.mkdir("/dev/shm/video0")
# Get sunset and sunrise times (sattools allnight program)
tsolar=subprocess.check_output(['allnight']).replace("\n","").split(" ")
# Convert to time structs
tset=time.strptime(tsolar[0]+" UTC", "%Y-%m-%dT%H:%M:%S %Z")
trise=time.strptime(tsolar[1]+" UTC", "%Y-%m-%dT%H:%M:%S %Z")
tnow=time.gmtime()
dtset=time.mktime(tset)-time.mktime(tnow)
dtrise=time.mktime(trise)-time.mktime(tnow)
# Wait for sunset
#if dtset>0:
# print time.strftime("%FT%T",time.gmtime())+" waiting for sunset (%ds)"%dtset
# time.sleep(dtset)
# Settings
device=cv2.VideoCapture(0)
device.set(3,720)
device.set(4,576)
# Set counter
iframe=1
# Start capture
print time.strftime("%FT%T",time.gmtime())+" start capture"
while dtrise>0:
# Get frame
ret,frame=device.read()
# Skip lost frames
if ret==True:
# Get time
t=float(time.time())
# Format time
nfd="%s.%03d"%(time.strftime("%Y-%m-%dT%T", time.gmtime(t)),int((t-np.floor(t))*1000))
# Get Size
ny,nx=frame.shape[0],frame.shape[1]
# Convert image to grayscale
gray=np.asarray(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)).astype(np.int8)
# Open output file
f=open("/dev/shm/video0/img%06d.pgm"%iframe,"w")
f.write("P5\n# %s\n%d %d\n255\n"%(nfd,nx,ny))
f.write(gray)
f.close()
# Log
if iframe%250==1:
print "%06d: %s %dx%d"%(iframe,nfd,nx,ny)
# Increment
iframe+=1
# Refresh time
tnow=time.gmtime()
dtrise=time.mktime(trise)-time.mktime(tnow)
# End capture
print time.strftime("%FT%T",time.gmtime())+" end capture"

135
python/compress.py 100644
View File

@ -0,0 +1,135 @@
#!/usr/bin/env python
import numpy as np
from astropy.time import Time
from astropy.io import fits
import time
import glob
import os
def read_pgm(fname):
# Open file
f=open(fname,"r")
# Read lines
line1=f.readline()
line2=f.readline()
line3=f.readline()
line4=f.readline()
# Read parameters
nfd=line2.split(" ")[1]
nx,ny=int(line3.split(" ")[0]),int(line3.split(" ")[1])
# Read image
z=np.fromfile(f,dtype='uint8',count=nx*ny).astype('float32')
# Close file
f.close()
return z,nfd
# Create fits file
def create_fits_file(nx,ny,nz,path,iframe):
# Allocate
z=np.empty(nz*ny*nx,dtype='float32').reshape(nz,nx*ny)
mjd=np.empty(nz,dtype='float64')
dt=np.empty(nz,dtype='float32')
# Loop over frames
tstart=time.time()
for i in xrange(nz):
z[i],nfd=read_pgm(path+"/img%06d.pgm"%(iframe+i))
# Format time
t=Time(nfd,format='isot')
if i==0:
t0=t
mjd[i]=t.mjd
dt[i]=86400.0*(mjd[i]-mjd[0])
print "Files read in %.3f s"%(time.time()-tstart)
# Compute statistics
tstart=time.time()
zmax=np.max(z,axis=0)
znum=np.argmax(z,axis=0)
z1=np.sum(z,axis=0)-zmax
z2=np.sum(z*z,axis=0)-zmax*zmax
zavg=z1/float(nz-1)
zstd=np.sqrt((z2-z1*zavg)/float(nz-2))
print "Statistics in %.3f s"%(time.time()-tstart)
# Reshape, reformat and flip
tstart=time.time()
zmax=np.flipud(zmax.astype('float32').reshape(ny,nx))
znum=np.flipud(znum.astype('float32').reshape(ny,nx))
zavg=np.flipud(zavg.astype('float32').reshape(ny,nx))
zstd=np.flipud(zstd.astype('float32').reshape(ny,nx))
z=np.array([zavg,zstd,zmax,znum])
print "Reshape in %.3f s"%(time.time()-tstart)
# Filename
fname="%s.fits"%t0
# Format header
hdr=fits.Header()
hdr['DATE-OBS']="%s"%t0
hdr['MJD-OBS']=t0.mjd
hdr['EXPTIME']=dt[-1]-dt[0]
hdr['NFRAMES']=nz
hdr['CRPIX1']=float(nx)/2.0
hdr['CRPIX2']=float(ny)/2.0
hdr['CRVAL1']=0.0
hdr['CRVAL2']=0.0
hdr['CD1_1']=1.0
hdr['CD1_2']=0.0
hdr['CD2_1']=0.0
hdr['CD2_2']=1.0
hdr['CTYPE1']="RA---TAN"
hdr['CTYPE2']="DEC--TAN"
hdr['CUNIT1']="deg"
hdr['CUNIT2']="deg"
hdr['CRRES1']=0.0
hdr['CRRES2']=0.0
hdr['EQUINIX']=2000.0
hdr['RADECSYS']="ICRS"
hdr['COSPAR']=4171
hdr['OBSERVER']="Cees Bassa"
for i in xrange(nz):
hdr['DT%04d'%i]=dt[i]
for i in xrange(10):
hdr['DUMY%03d'%i]=0.0
# Write fits file
hdu=fits.PrimaryHDU(data=z,header=hdr)
hdu.writeto(fname,clobber=True)
return fname
# Main function
if __name__ == '__main__':
# Settings
nx=720
ny=576
nz=250
path="/dev/shm/video0"
# Start forever loop
while True:
# Find files
files=sorted(glob.glob(path+"/img??????.pgm"))
# Enough files
if len(files)>nz:
# Get first frame
iframe=int(files[0].replace(path+"/img","").replace(".pgm",""))
tstart=time.time()
fname=create_fits_file(nx,ny,nz,path,iframe)
tend=time.time()
print "Created %s in %.2f"%(fname,tend-tstart)
# Remove files
for i in xrange(nz):
os.remove(path+"/img%06d.pgm"%(iframe+i))
else:
time.sleep(1)

View File

@ -732,6 +732,7 @@ int main(int argc,char *argv[])
cpgopen("/xs");
cpgpap(0.,1.0);
//cpgpap(7,0.75);
cpgask(0);
cpgsch(0.8);
@ -1101,6 +1102,38 @@ int main(int argc,char *argv[])
redraw=1;
continue;
}
if (c=='h'){
printf("Reduce Satellite tracks. ");
printf("q Quit\n");
printf("TAB track and stack objects automatically (only classfd sats)\n");
printf("w write IOD observation to observations.txt\n");
printf("M/D measure stack and track position (also middle mouse button)\n");
printf("e change fraction (0.0 to start, 0.5 for medium, 1.0 for the end)\n");
printf("d provide NORAD satellite number\n");
printf("C toggle IOD observing conditions G-Good F-Fair P-Poor B-Bad T-Terrible E-Excellent\n");
printf("B toggle behavior of sat.: F-Flash I-Irregular R-Regular S-Steady X-Uspecified E-Extremely weak\n");
printf("s select start of satellite track\n");
printf("f select end of satellite track\n");
printf("F fit satellite track\n");
printf("+/= Increase level of masking pixels\n");
printf("- Lower level for masking pixels (This does not seem to work)\n");
printf("1 go to the mean pixel value FITS layer\n");
printf("2 go to the FITS standard deviation layer\n");
printf("3 go to the maximum pixel value FITS layer\n");
printf("4 go to the frame number of the maximum pixel value FITS layer\n");
printf("5 go to the stack and track layer (only after 't' or 'TAB')\n");
printf("v lower dynamic range\n");
printf("b increase dynamic range\n");
printf("c center on cursor\n");
printf("z zoom in at cursor\n");
printf("x zoom out at cursor\n");
printf("R/r reset to start\n");
printf("m measure position of pixel\n");
printf("t track & stack, give NORAD satellite number\n");
printf("E change fraction in tenths\n");
printf("X pixel mask (also with mouse scroll wheel)\n");
}
}
cpgend();

View File

@ -16,7 +16,7 @@
#define MAXPORT 7274
#define IP "127.0.0.1"
#define LIM 2048
#define NMAX 128
#define NMAX 256
#define SCHEDULED 0
#define STARTED 1
@ -24,13 +24,14 @@
// Observation struct contains observation time, celestial coords and camera name
struct observation {
char stime[20],sra[15],sde[15],camname[15];
char stime[20],sra[15],sde[15],camname[15],startstop[10];
time_t ptime;
float dt;
};
int fgetline(FILE *file,char *s,int lim);
void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname);
void stop_obs(char *datadir,char *obsdir,char *camname);
time_t decode_time(char *stm);
int main(int argc, char *argv[])
@ -43,6 +44,7 @@ int main(int argc, char *argv[])
struct observation obs[NMAX];
char *env;
char datadir[128],obsdir[128];
int nextobs, dtnext;
// Get environment variables
env=getenv("ST_DATADIR");
@ -66,7 +68,7 @@ int main(int argc, char *argv[])
i=0;
file=fopen("schedule.txt","r");
while (fgetline(file,line,LIM)>0) {
sscanf(line,"%s %s %s %s",obs[i].stime,obs[i].sra,obs[i].sde,obs[i].camname);
sscanf(line,"%s %s %s %s %s",obs[i].stime,obs[i].sra,obs[i].sde,obs[i].camname,obs[i].startstop);
obs[i].ptime=decode_time(obs[i].stime);
i++;
@ -90,20 +92,35 @@ int main(int argc, char *argv[])
// printf("%s\n",ctime(&rawtime));
// Compute time differences
for (i=0;i<nobs;i++)
for (i=0;i<nobs;i++) {
obs[i].dt=difftime(obs[i].ptime,rawtime);
}
nextobs=-1;
dtnext=9999999;
// Loop over observations
for (i=0;i<nobs;i++) {
if (obs[i].dt>0.0) {
printf("%4.0f %s %s %s\n",obs[i].dt,obs[i].stime,obs[i].sra,obs[i].sde);
break;
if(obs[i].dt < dtnext){
nextobs=i;
dtnext=obs[i].dt;
}
// printf("%4.0f %s %s %s %s\n",obs[i].dt,obs[i].stime,obs[i].sra,obs[i].sde,obs[i].startstop);
// break;
} else if (obs[i].dt==0) {
printf("Slewing to %s %s\n",obs[i].sra,obs[i].sde);
send_position(obs[i].sra,obs[i].sde,datadir,obsdir,obs[i].camname);
if(strstr(obs[i].startstop,"tart")!=NULL){
//printf("Slewing to %s %s\n",obs[i].sra,obs[i].sde);
send_position(obs[i].sra,obs[i].sde,datadir,obsdir,obs[i].camname);
} else if(strstr(obs[i].startstop,"top")!=NULL){
stop_obs(datadir,obsdir,obs[i].camname);
}
}
}
if(nextobs>=0){
// print next observation data if any found
printf("%4.0f %s %s %s %s\n",obs[nextobs].dt,obs[nextobs].stime,obs[nextobs].sra,obs[nextobs].sde,obs[nextobs].startstop);
}
// Sleep
sleep(1);
}
@ -160,40 +177,53 @@ void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname)
FILE *file;
float ra,de;
char camera[128],fname[128];
float f;
char s[31];
// Check if camera is fixed
// read complete line from data/cameras.txt describing the scheduled camera
read_cameras(camname,datadir,camera); // search for camera name
sscanf(camera,"%s %f %f %f %f %s", s, &f, &f, &f, &f, s);
// Look for "fix" string to jump over slewing routines.
if(strstr(s,"ix")==NULL){
// Old packet style
// sprintf(packet,"<newNumberVector device='Celestron GPS' name='EQUATORIAL_EOD_COORD_REQUEST'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",sra,sde);
// Old packet style
// sprintf(packet,"<newNumberVector device='Celestron GPS' name='EQUATORIAL_EOD_COORD_REQUEST'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",sra,sde);
// New packet style (as of 2013-08-20)
sprintf(packet,"<newNumberVector device='Celestron GPS' name='EQUATORIAL_EOD_COORD'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",sra,sde);
// New packet style (as of 2013-08-20)
sprintf(packet,"<newNumberVector device='Celestron GPS' name='EQUATORIAL_EOD_COORD'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",sra,sde);
// Send TCP packet
skt=socket(AF_INET,SOCK_STREAM,0);
addr.sin_family=AF_INET;
port=PORT;
addr.sin_port=htons(port);
he=gethostbyname(IP);
bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length);
while((connect(skt,(struct sockaddr *) &addr,sizeof(addr))<0) && (port < MAXPORT)) {
fprintf(stderr,"Connection refused by remote host on port %04d.\n",port);
port++;
// Skip port 7265... used by some other service?
if(port==7265) port++;
fprintf(stderr,"Trying port %04d.\n",port);
printf("Slewing to %s %s\n",sra,sde);
// Send TCP packet
skt=socket(AF_INET,SOCK_STREAM,0);
addr.sin_family=AF_INET;
port=PORT;
addr.sin_port=htons(port);
he=gethostbyname(IP);
bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length);
while((connect(skt,(struct sockaddr *) &addr,sizeof(addr))<0) && (port < MAXPORT)) {
fprintf(stderr,"Connection refused by remote host on port %04d.\n",port);
port++;
// Skip port 7265... used by some other service?
if(port==7265) port++;
fprintf(stderr,"Trying port %04d.\n",port);
addr.sin_port=htons(port);
he=gethostbyname(IP);
bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length);
}
if(port>=MAXPORT) return;
printf("Connected to Indi server on port %04d.\n",port);
write(skt,packet,strlen(packet));
close(skt);
}
if(port>=MAXPORT) return;
printf("Connected to Indi server on port %04d.\n",port);
write(skt,packet,strlen(packet));
close(skt);
printf("Starting new observation\n");
// Set restart
sprintf(fname,"%s/control/state.txt",obsdir);
file=fopen(fname,"w");
@ -211,8 +241,6 @@ void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname)
}
// Set camera
// camera.txt control file with complete line from data/cameras.txt describing the scheduled camera
read_cameras(camname,datadir,camera); // search for camera name
sprintf(fname,"%s/control/camera.txt",obsdir);
file=fopen(fname,"w");
if (file!=NULL) {
@ -223,6 +251,34 @@ void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname)
return;
}
// Send stop observation signal
void stop_obs(char *datadir,char *obsdir,char *camname)
{
FILE *file;
char camera[128],fname[128];
float f;
char s[31];
// Retrieve Camera data
// read complete line from data/cameras.txt describing the scheduled camera
read_cameras(camname,datadir,camera); // search for camera name
sscanf(camera,"%s %f %f %f %f %s", s, &f, &f, &f, &f, s);
printf("Stop observation\n");
// Set stop
sprintf(fname,"%s/control/state.txt",obsdir);
file=fopen(fname,"w");
if (file!=NULL) {
fprintf(file,"stop");
fclose(file);
}
return;
}
// Decode time
time_t decode_time(char *stm)
{

View File

@ -0,0 +1,182 @@
#!/bin/bash
echo "Step 1.1: install dependencies"
sleep 1
apg-get update
apt-get install ntp eog emacs gfortran libpng-dev libx11-dev libjpeg-dev libexif-dev git dos2unix sextractor
echo "Step 1.2: goto /usr/local/src"
sleep 1
cd /usr/local/src
echo "Step 2.1: download pgplot"
sleep 1
wget -c ftp://ftp.astro.caltech.edu/pub/pgplot/pgplot5.2.tar.gz
echo "Step 2.2: unpack pgplot"
sleep 1
gunzip -c pgplot5.2.tar.gz | tar xvf -
echo "Step 2.3: create pgplot directory"
sleep 1
mkdir -p /usr/local/src/pgplot-5.2.2
echo "Step 2.4: select drivers"
sleep 1
# Selecting PNDRIV, PSDRIV and XWDRIV
sed -e "s/! PNDRIV/ PNDRIV/g" -e "s/! PSDRIV/ PSDRIV/g" -e "s/! XWDRIV/ XWDRIV/g" pgplot/drivers.list >pgplot-5.2.2/drivers.list
echo "Step 2.5: create makefile"
sleep 1
cd /usr/local/src/pgplot-5.2.2
../pgplot/makemake ../pgplot linux g77_gcc
echo "Step 2.6: adjusting makefile"
sleep 1
sed -i -e "s/FCOMPL=g77/FCOMPL=gfortran/g" makefile
sed -i -e "s/FFLAGC=-u -Wall -fPIC -O/FFLAGC=-ffixed-form -ffixed-line-length-none -u -Wall -fPIC -O/g" makefile
sed -i -e "s|pndriv.o : ./png.h ./pngconf.h ./zlib.h ./zconf.h|pndriv.o : |g" makefile
echo "Step 2.7: run make"
sleep 1
make
make cpg
echo "Step 2.8: place libraries and header files"
sleep 1
rm -rf /usr/local/lib/libpgplot.a /usr/local/lib/libcpgplot.a /usr/local/lib/libpgplot.so /usr/local/include/cpgplot.h
ln -s /usr/local/src/pgplot-5.2.2/libpgplot.a /usr/local/lib/
ln -s /usr/local/src/pgplot-5.2.2/libpgplot.so /usr/local/lib/
ln -s /usr/local/src/pgplot-5.2.2/libcpgplot.a /usr/local/lib/
ln -s /usr/local/src/pgplot-5.2.2/cpgplot.h /usr/local/include/
echo "Step 2.9: clean up"
sleep 1
rm -rf /usr/local/src/pgplot5.2.tar.gz /usr/local/src/pgplot
echo "Step 3.1: download qfits"
sleep 1
cd /usr/local/src
wget -c ftp://ftp.eso.org/pub/qfits/qfits-5.2.0.tar.gz
echo "Step 3.2: unpack qfits"
sleep 1
gunzip -c qfits-5.2.0.tar.gz | tar xvf -
echo "Step 3.3: fix xmemory.c"
sleep 1
cd /usr/local/src/qfits-5.2.0
chmod +w src/xmemory.c
sed -i -e "s/swapfd = open(fname, O_RDWR | O_CREAT);/swapfd = open(fname, O_RDWR | O_CREAT, 0644);/g" src/xmemory.c
echo "Step 3.4: configure and make"
sleep 1
./configure
make
make install
echo "Step 3.5: clean up"
sleep 1
rm /usr/local/src/qfits-5.2.0.tar.gz
echo "Step 4.1: download wcslib-2.9"
sleep 1
cd /usr/local/src
wget -c "https://drive.google.com/uc?export=download&id=0B-15JZVdjJi4QW0zZmZUM1ZXblU" -O wcslib-2.9.tar
#wget -c http://www.epta.eu.org/~bassa/wcslib-2.9.tar
echo "Step 4.2: unpack wcslib"
sleep 1
tar -xvf wcslib-2.9.tar
echo "Step 4.3: compile wcslib"
sleep 1
cd /usr/local/src/wcslib-2.9/C/
make clean
rm libwcs_c.a
make
echo "Step 4.4: place libraries and header files"
sleep 1
rm -rf /usr/local/lib/libwcs_c.a /usr/local/include/proj.h /usr/local/include/cel.h
ln -s /usr/local/src/wcslib-2.9/C/libwcs_c.a /usr/local/lib/
ln -s /usr/local/src/wcslib-2.9/C/proj.h /usr/local/include/
ln -s /usr/local/src/wcslib-2.9/C/cel.h /usr/local/include/
echo "Step 4.5: clean up"
sleep 1
rm -rf /usr/local/src/wcslib-2.9.tar
echo "Step 5.1: download gsl"
sleep 1
cd /usr/local/src
wget -c ftp://ftp.gnu.org/gnu/gsl/gsl-1.16.tar.gz
echo "Step 5.2: unpack gsl"
sleep 1
gunzip -c gsl-1.16.tar.gz | tar xvf -
echo "Step 5.3: configure, make, make install"
sleep 1
cd /usr/local/src/gsl-1.16/
./configure
make
make install
echo "Step 5.4: clean up"
sleep 1
rm -rf /usr/local/src/gsl-1.16.tar.gz
echo "Step 6.1: set ld.so.conf"
sleep 1
echo "include /etc/ld.so.conf.d/*.conf" >/etc/ld.so.conf
echo "/usr/local/lib" >>/etc/ld.so.conf
ldconfig
echo "Step 6.1: download fftw"
sleep 1
cd /usr/local/src
wget http://www.fftw.org/fftw-3.3.4.tar.gz
echo "Step 6.2: unpack fftw"
sleep 1
gunzip -c fftw-3.3.4.tar.gz | tar xvf -
echo "Step 6.3: configure, make,make install"
sleep 1
cd /usr/local/src/fftw-3.3.4
./configure --enable-float
make
make install
echo "Step 6.4: clean up"
sleep 1
rm -rf /usr/local/src/fftw-3.3.4.tar.gz
echo "Step 7.1: download ffmpeg"
sleep 1
cd /usr/local/src
wget http://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
echo "Step 7.2: unpack ffmpeg"
sleep 1
bzip2 -cd ffmpeg-snapshot.tar.bz2 | tar xvf -
echo "Step 7.3: patch pgmenc.c"
sleep 1
cd /usr/local/src/ffmpeg/libavcodec
wget -c -O pnmenc.c "https://drive.google.com/uc?export=download&id=0B-15JZVdjJi4YnVEdXEzVmExVEU"
#wget https://dl.dropboxusercontent.com/u/52579487/pnmenc.c -O pnmenc.c
echo "Step 7.4: configure, make,make install"
sleep 1
cd /usr/local/src/ffmpeg
./configure --disable-yasm
make
make install
echo "Step 7.5: clean up"
cd /usr/local/src
rm -rf ffmpeg-snapshot.tar.bz2
echo "Done installing dependencies"

View File

@ -0,0 +1,53 @@
#!/bin/bash
echo "Step 1.1: make directory"
sleep 1
mkdir -p $HOME/code/c/satellite/
cd $HOME/code/c/satellite
echo "Step 1.2: clone sattools repository (may take a while)"
sleep 1
#git clone https://github.com/cbassa/sattools.git
git clone https://github.com/fmederos/sattools.git
echo "Step 1.3: make"
sleep 1
cd $HOME/code/c/satellite/sattools
make
echo "Step 1.4: clone strf repository"
sleep 1
cd $HOME/code/c/satellite
git clone https://github.com/cbassa/strf.git
echo "Step 1.5: make"
sleep 1
cd $HOME/code/c/satellite/strf
make
echo "Step 1.6: download classfd.tle"
sleep 1
mkdir -p $HOME/code/c/satellite/sattools/tle
cd $HOME/code/c/satellite/sattools/tle
wget -c https://www.prismnet.com/~mmccants/tles/classfd.zip
unzip classfd.zip
dos2unix classfd.tle
rm classfd.zip
echo "Step 2.1: set environment variables"
sleep 1
cd
echo "export PGPLOT_DIR=/usr/local/src/pgplot-5.2.2" >>$HOME/.xsessionrc
echo "export ST_COSPAR=4171" >>$HOME/.xsessionrc
echo "export ST_DATADIR=$HOME/code/c/satellite/sattools" >>$HOME/.xsessionrc
echo "export ST_TLEDIR=$HOME/code/c/satellite/sattools/tle" >>$HOME/.xsessionrc
echo "export ST_OBSDIR=$HOME/satobs" >>$HOME/.xsessionrc
mkdir $ST_OBSDIR
mkdir $ST_OBSDIR/control
echo "Step 2.2: set path"
sleep 1
echo "PATH=$HOME/code/c/satellite/sattools:$HOME/code/c/satellite/sattools/scripts:$HOME/software/strf:\$PATH" >>$HOME/.profile
echo "Final step: run"
echo "source $HOME/.profile"

View File

@ -0,0 +1,31 @@
#./bin/bash
# Loop into every directory
for obsdir in *; do
if [ -d $obsdir ]; then
echo $obsdir
cd $obsdir
# check if observation is calibrated
if [ ! -e "out.dat" ]; then
CALFRAME=1
while true; do
# calibrate Nth image captured
st_calibrate.sh $CALFRAME
# check if no calibration data was output
if [ ! -e "out.dat" ]; then
read -p "Delete observation?" yn
case $yn in
[Yy]* ) cd ..; rm -rf $obsdir; break;;
[Nn]* ) CALFRAME=$(($CALFRAME+1)); continue;;
* ) echo "Please answer y or n.";;
esac
else
cd ..
break
fi
done
else
cd ..
fi
fi
done

View File

@ -1,7 +1,15 @@
#!/bin/bash
if [ -z $1 ]; then
N=10
else
echo "Using image $1 to calibrate"
N=$1
rm test.fits
fi
if [ ! -e "test.fits" ]; then
ls -1 2*.fits | head -n10 | tail -n1 | awk '{printf("cp %s test.fits\n",$1)}' | sh
ls -1 2*.fits | head -n$N | tail -n1 | awk '{printf("cp %s test.fits\n",$1)}' | sh
fi
sextractor test.fits -c $ST_DATADIR/sextractor/default.sex
mv test.cat test.fits.cat

View File

@ -16,3 +16,4 @@ rm img*.pgm
# Start capture
ffmpeg -f video4linux2 -i $device -s 720x576 -r 25 img%06d.pgm

View File

@ -0,0 +1,26 @@
#!/bin/bash
# Check obsdir exists
if [ ! -d $ST_OBSDIR ]; then
mkdir $ST_OBSDIR
fi
if [ ! -d $ST_OBSDIR/control ]; then
mkdir $ST_OBSDIR/control
fi
# look for observations in every subdir
# catenate each one to lastobs.txt in obsdir
find $ST_OBSDIR -iname 'observations.txt' | awk '{printf ("cat %s\n",$1)}' | sh > $ST_OBSDIR/lastobs.txt
# and rename each original obs files to *.txt.used
find $ST_OBSDIR -iname 'observations.txt' | awk '{printf ("mv %s %s.used\n",$1,$1)}' | sh
# catenate lastobs.txt to allobs.txt and count the new observations
cat $ST_OBSDIR/lastobs.txt >> $ST_OBSDIR/allobs.txt
# count total observations
NOBS=`cat $ST_OBSDIR/lastobs.txt | wc -l`
NALLOBS=`cat $ST_OBSDIR/allobs.txt | wc -l`
echo "$NOBS new observations in lastobs.txt, total observations in allobs.txt: $NALLOBS"

View File

@ -0,0 +1,12 @@
[Desktop Entry]
Encoding=UTF-8
Version=0.9.4
Type=Application
Name=ST_Compress
Comment=
Exec=st_compress.sh
OnlyShowIn=XFCE;
StartupNotify=false
Terminal=true
Hidden=false

2
scripts/st_compress.sh 100755 → 100644
View File

@ -35,7 +35,7 @@ while true; do
pgm2fits -p $PGMDIR/img -w 720 -h 576 -s $M -n $N
# Remove files
ls -1 $PGMDIR/img*.pgm | head -n$N | awk '{printf("sudo rm -rf %s\n",$1)}' | sh
ls -1 $PGMDIR/img*.pgm | head -n$N | awk '{printf("rm -rf %s\n",$1)}' | sh
# Run viewer
viewer `ls -1 2*.fits | tail -n1`

View File

@ -0,0 +1,144 @@
#!/bin/bash
source ~/.bashrc
# Settings
PGMDIR=/dev/shm
N=250
# If no images are found during this period (seconds), relaunch capture process
WAIT=20
COUNT=0
# Start automatically capture process or not
AUTOSTART=1
# Default camera to start imaging if no schedule is available
CAMERADEV="/dev/video1"
CAPTUREPID=0
# Check obsdir exists
if [ ! -d $ST_OBSDIR ]; then
mkdir $ST_OBSDIR
fi
if [ ! -d $ST_OBSDIR/control ]; then
mkdir $ST_OBSDIR/control
fi
# if autostart force a restart
if [ $AUTOSTART == 1 ]; then
echo "restart" >$ST_OBSDIR/control/state.txt
STATE="restart"
else
echo "stop" >$ST_OBSDIR/control/state.txt
STATE="stop"
fi
export CAMERADEV=`cat $ST_OBSDIR/control/camera.txt | awk '{print $((7))}'`
echo "Status: "$STATE
# For ever loop
while true; do
# Get state
export STATE=`cat $ST_OBSDIR/control/state.txt`
# Create new directory
if [ $STATE == "restart" ]; then
export DIR=`date -u +%FT%T | sed -e "s/-//g" -e "s/\://g" -e "s|T|/|g"`
mkdir -p $ST_OBSDIR/$DIR
cd $ST_OBSDIR/$DIR
echo "Moving to $ST_OBSDIR/$DIR"
echo "observing" >$ST_OBSDIR/control/state.txt
cp $ST_OBSDIR/control/position.txt .
# cp $ST_OBSDIR/control/scale.txt .
cp $ST_OBSDIR/control/camera.txt .
# Register time offset against NTP server
ntpdate -q uy.pool.ntp.org > ntpresult.txt &
export CAMERADEV=`cat $ST_OBSDIR/control/camera.txt | awk '{print $((7))}'`
# Remove old captured frames
echo "Removing all captured frames"
# ls -1 $PGMDIR/img*.pgm | awk '{printf("sudo rm -rf %s\n",$1)}' | sh
#ls -1 $PGMDIR/img*.pgm | awk '{printf("rm -rf %s\n",$1)}' | sh
find $PGMDIR -type f -name './img*.pgm' | awk '{printf("rm -rf %s\n",$1)}' | sh
fi
# kill capture process just when scheduler sends stop signal
if [ $STATE == "stop" ]; then
if [ $(($CAPTUREPID)) != 0 ]; then
echo ""
echo "Stopping capture process"
kill -9 $CAPTUREPID
CAPTUREPID=0
fi
fi
# Get number of captured frames
NFILES=`ls -1 $PGMDIR/img*.pgm 2>/dev/null | wc -l`
#NFILES=`find $PGMDIR -type f -name 'img*.pgm' |wc -l`
# If enough, process
if [ $NFILES -ge $N ]; then
COUNT=0
echo ""
echo "Compressing $N captured frames"
# Start point
M=`ls -1 $PGMDIR/img*.pgm | head -n1 | sed -e "s/[^0-9]*//g"`
# Run pgm2fits
# pgm2fits -p $PGMDIR/img -w 720 -h 576 -s $M -n $N
pgm2fits -p $PGMDIR/img -w 720 -h 576 -s $M -n $N >/dev/null
# Run viewer
viewer `ls -1 2*.fits | tail -n1`
cp avg.pgm $ST_OBSDIR
# Remove files
echo ""
echo "Removing $N captured frames"
# ls -1 $PGMDIR/img*.pgm | head -n$N | awk '{printf("sudo rm -rf %s\n",$1)}' | sh
ls -1 $PGMDIR/img*.pgm | head -n$N | awk '{printf("rm -rf %s\n",$1)}' | sh
#find $PGMDIR -type f -name 'img*.pgm' | head -n$N | awk '{printf("rm -rf %s\n",$1)}' | sh
# echo "Finished"
else
# There are not enough captured frames
# Launch capture process if state is not stop
# if time passes with still no images re-launch capture process
if [ $STATE != "stop" ]; then
echo ""
echo "Waiting for frames. Status: "$STATE
COUNT=$(($COUNT+1))
if [ $COUNT -ge $WAIT ]; then
COUNT=0
echo ""
echo "No frames found, restarting capture script"
# sh $ST_DATADIR/scripts/st_capture.sh /dev/video-$CAMERA &
sh $ST_DATADIR/scripts/st_capture.sh $CAMERADEV &
sleep 1
CAPTUREPID=`pgrep -o -x ffmpeg`
fi
# if restarting then relaunch capture script now
if [ $STATE == "restart" ]; then
if [ $(($CAPTUREPID)) == 0 ]; then
echo "Restarting capture script"
# sh $ST_DATADIR/scripts/st_capture.sh /dev/video-$CAMERA &
sh $ST_DATADIR/scripts/st_capture.sh $CAMERADEV &
sleep 1
CAPTUREPID=`pgrep -o -x ffmpeg`
COUNT=0
fi
fi
else
# we are stopped, check for bogus capture process
# echo "Status: "$STATE
if [ $(($CAPTUREPID)) != 0 ]; then
echo "Stopping capture process"
kill -9 $CAPTUREPID
CAPTUREPID=0
fi
fi
fi
# Sleep
sleep 1
done

View File

@ -0,0 +1,12 @@
[Desktop Entry]
Encoding=UTF-8
Version=0.9.4
Type=Application
Name=EOG
Comment=
Exec=st_eog.sh
OnlyShowIn=XFCE;
StartupNotify=false
Terminal=false
Hidden=false

View File

@ -0,0 +1,7 @@
#!/bin/bash
source ~/.bashrc
cd $ST_OBSDIR
eog avg.pgm

View File

@ -0,0 +1,18 @@
#./bin/bash
# Loop into every directory
for obsdir in *; do
if [ -d $obsdir ]; then
echo $obsdir
cd $obsdir
# check if observation is not already processed
N=`ls -1 ./2*.fits 2>/dev/null | wc -l`
if [ $N -ge 1 ]; then
# process observation frames in directory
st_process_offline.sh $1
fi
cd ..
fi
done

View File

@ -7,7 +7,12 @@ for file in 2*.fits; do
mv test.cat $file.cat
# Run addwcs
addwcs -f $file -r test.fits
if [ -z $1 ]; then
addwcs -f $file -r test.fits
else
echo "Limiting magnitude of star catalog to $1"
addwcs -f $file -r test.fits -m $1
fi
# Run satid
satid $file $file.png/png 2>/dev/null
@ -15,3 +20,4 @@ for file in 2*.fits; do
# Move calibrated file
mv $file.cat $file.cal $file.id $file $file.png png/
done

View File

@ -0,0 +1 @@
for file in png/2*.fits; do reduce $file;done

View File

@ -0,0 +1 @@
ristretto png/*.png

View File

@ -0,0 +1,12 @@
[Desktop Entry]
Encoding=UTF-8
Version=0.9.4
Type=Application
Name=Runshed
Comment=
Exec=st_runsched.sh
OnlyShowIn=XFCE;
StartupNotify=false
Terminal=true
Hidden=false

View File

@ -0,0 +1,7 @@
#!/bin/bash
source ~/.bashrc
cd $ST_DATADIR
runsched

34
scripts/stget.sh 100755
View File

@ -0,0 +1,34 @@
#!/bin/bash
# Get date
DATE=`date +%Y%m%d_%H%M%S`
# Get cookie
wget --post-data='identity=yourlogin&password=yourpassword' --cookies=on --keep-session-cookies --save-cookies=/tmp/cookies.txt 'https://www.space-track.org/ajaxauth/login' -o /tmp/stget.log
# Get data
wget --keep-session-cookies --load-cookies=/tmp/cookies.txt 'https://www.space-track.org/basicspacedata/query/class/tle_latest/ORDINAL/1/EPOCH/%3Enow-30/format/3le' -O $ST_TLEDIR/catalog.tle
dos2unix $ST_TLEDIR/catalog.tle
sed -i -e "s/^1 /1 0000/g" -e "s/^2 /2 0000/g" -e "s/^1 /1 000/g" -e "s/^2 /2 000/g" -e "s/^1 /1 00/g" -e "s/^2 /2 00/g" -e "s/^1 /1 0/g" -e "s/^2 /2 0/g" $ST_TLEDIR/catalog.tle
cp $ST_TLEDIR/catalog.tle $ST_TLEDIR/${DATE}_catalog.txt
# Get classfd
wget http://www.prismnet.com/~mmccants/tles/classfd.zip --no-check-certificate -O $ST_TLEDIR/classfd.zip
unzip -o $ST_TLEDIR/classfd.zip
dos2unix $ST_TLEDIR/classfd.tle
cp $ST_TLEDIR/classfd.tle $ST_TLEDIR/${DATE}_classfd.txt
#mv $HOME/classfd.tle $ST_TLEDIR/classfd.tle
rm $ST_TLEDIR/classfd.zip
# Get inttles
wget http://www.prismnet.com/~mmccants/tles/inttles.zip --no-check-certificate -O $ST_TLEDIR/inttles.zip
unzip -o $ST_TLEDIR/inttles.zip
dos2unix $ST_TLEDIR/inttles.tle
cp $ST_TLEDIR/inttles.tle $ST_TLEDIR/${DATE}_inttles.txt
#mv $HOME/inttles.tle $ST_TLEDIR/inttles.tle
rm $ST_TLEDIR/inttles.zip
#rm $HOME/login
# Create bulk file
cat $ST_TLEDIR/classfd.tle $ST_TLEDIR/catalog.tle >$ST_TLEDIR/bulk.tle

View File

@ -37,7 +37,7 @@ PHOT_AUTOPARAMS 2.5, 3.5 # MAG_AUTO parameters: <Kron_fact>,<min_radius>
SATUR_LEVEL 50000.0 # level (in ADUs) at which arises saturation
MAG_ZEROPOINT 0.0 # magnitude zero-point
MAG_ZEROPOINT 11.0 # magnitude zero-point
MAG_GAMMA 4.0 # gamma of emulsion (for photographic scans)
GAIN 0.0 # detector gain in e-/ADU.
PIXEL_SCALE 1.0 # size of pixel in arcsec (0=use FITS WCS info).

View File

@ -128,7 +128,7 @@ void usage()
printf("R R.A.\n");
printf("D Decl.\n");
printf("A Azimuth\n");
printf("E Elecation\n");
printf("E Elevation\n");
printf("S All night\n");
printf("h this help\n");
printf("s site (COSPAR)\n");
@ -637,7 +637,8 @@ int main(int argc,char *argv[])
}
}
init_plot("/xs",10,0.75);
// init_plot("/xs",10,0.75);
init_plot("/xs",8,0.75);
plot_skymap();
@ -862,7 +863,7 @@ void init_plot(char *psfile,float width,float aspect)
}
// Add to schedule
void schedule(char *nfd,double ra,double de)
void schedule(char *nfd,double ra,double de,char *startstop)
{
FILE *file;
char sra[16],sde[16];
@ -871,15 +872,15 @@ void schedule(char *nfd,double ra,double de)
dec2sex(ra/15.0,sra,0,5);
dec2sex(de,sde,0,4);
printf("%s %s %s\n",nfd,sra,sde);
printf("%s %s %s %s\n",nfd,sra,sde,startstop);
// Open file
file=fopen("schedule.txt","a");
if (file==NULL) {
printf("Failed to create schedule.txt\n");
return;
}
fprintf(file,"%s %s %s %s\n",nfd,sra,sde, m.camera);
fprintf(file,"%s %s %s %s %s\n",nfd,sra,sde, m.camera,startstop);
fclose(file);
return;
@ -2223,6 +2224,8 @@ void skymap_plotsun(void)
int read_camera(int no)
{
int i=0;
float f,f2;
char s[31];
FILE *file;
char line[LIM],filename[LIM];
@ -2237,7 +2240,15 @@ int read_camera(int no)
if (strstr(line,"#")!=NULL)
continue;
if (i==no) {
sscanf(line,"%s %f %f", m.camera, &m.fw, &m.fh);
f2=-90;
// Retrieve complete line of selected camera parameters
sscanf(line,"%s %f %f %f %f %s %s %f %f", m.camera, &m.fw, &m.fh, &f, &f, s, s, &f, &f2);
if(f2>=0){
// if Elevation is set, center map to camera position
m.azi0=(double)f;
m.alt0=(double)f2;
horizontal2equatorial(m.mjd,m.azi0,m.alt0,&m.ra0,&m.de0);
}
m.fw*=0.5;
m.fh*=0.5;
return 0;
@ -2259,6 +2270,12 @@ int plot_skymap(void)
double ra,de,azi,alt,rx,ry;
xyz_t sunpos;
status=read_camera(fov);
if (status==-1) {
fov=0;
status=read_camera(fov);
}
for (;;) {
if (redraw>0) {
// Get present mjd
@ -2309,12 +2326,6 @@ int plot_skymap(void)
if (fov>=0) {
cpgsfs(2);
status=read_camera(fov);
if (status==-1) {
fov=0;
status=read_camera(fov);
}
cpgrect(-m.fw,m.fw,-m.fh,m.fh);
cpgsfs(1);
}
@ -2466,7 +2477,8 @@ int plot_skymap(void)
printf("v Toggle visibility contours\n");
printf("F Toggle camera configuration (data/cameras.txt)\n");
printf("TAB Cycle IOD observations\n");
printf("S Save position/time to schedule\n");
printf("S Save observation position/time to schedule\n");
printf("E Save observation end-time to schedule\n");
printf("a Select on age\n");
printf("Q Toggle plotting stars\n");
}
@ -2579,6 +2591,11 @@ int plot_skymap(void)
// Toggle focal length
if (c=='F') {
fov++;
status=read_camera(fov);
if (status==-1) {
fov=0;
status=read_camera(fov);
}
redraw=1;
}
@ -2655,7 +2672,11 @@ int plot_skymap(void)
// Add to schedule
if (c=='S')
schedule(m.nfd,m.ra0,m.de0);
schedule(m.nfd,m.ra0,m.de0,"start");
// Add to schedule
if (c=='E')
schedule(m.nfd,m.ra0,m.de0,"stop");
// Polar
if (c=='z') {