COSMOS core  1.0.2 (beta)
Comprehensive Open-architecture Solution for Mission Operations Systems
Collaboration diagram for Physics Library functions:

Functions

void pleph_ (double[], long *, long *, double[])
 
void dpleph_ (double[], long *, long *, double[])
 
rvector gravity_vector (svector pos, int model, uint32_t degree)
 
double gravity_potential (double lon, double lat, double r, int model, uint32_t degree)
 
rvector gravity_accel (posstruc pos, int model, uint32_t degree)
 Calculates geocentric acceleration vector from chosen model. More...
 
rvector gravity_accel2 (posstruc pos, int model, uint32_t degree)
 Calculates geocentric acceleration vector from chosen model. More...
 
double gravity (double radius, double colat, double elon, int model, uint32_t degree)
 Calculates geocentric acceleration magnitude from chosen model. More...
 
int32_t gravity_params (int model)
 Gravitational model parameters. More...
 
double nplgndr (uint32_t l, uint32_t m, double x)
 Legendre polynomial. More...
 
svector groundstation (locstruc &satellite, locstruc &groundstation)
 Ground station values. More...
 
void simulate_hardware (cosmosstruc *cinfo, locstruc &loc)
 Simulate all devices. More...
 
void simulate_hardware (cosmosstruc *cinfo, vector< locstruc > &locvec)
 Simulate Hardware data - multiple. More...
 
void initialize_imu (uint16_t index, devspecstruc &devspec, locstruc &loc)
 Initialize IMU simulation. More...
 
void simulate_imu (int index, cosmosstruc *root, locstruc &loc)
 Simulated IMU values. More...
 
int32_t pos_accel (physicsstruc &physics, locstruc &loc)
 Acceleration. More...
 
void att_accel (physicsstruc &physics, locstruc &loc)
 Torque. More...
 
void geod2icrf (posstruc *pos)
 Geodetic to Heliocentric. More...
 
double msis86_density (posstruc pos, float f107avg, float f107, float magidx)
 
double msis00_density (posstruc pos, float f107avg, float f107, float magidx)
 Calculate atmospheric density. More...
 
void orbit_init_tle (int32_t mode, double dt, double mjd, cosmosstruc *root)
 
void orbit_init_eci (int32_t mode, double dt, double mjd, cartpos ipos, cosmosstruc *root)
 
void orbit_init_shape (int32_t mode, double dt, double mjd, double altitude, double angle, double hour, cosmosstruc *root)
 
void propagate (cosmosstruc *root, double mjd)
 
double rearth (double lat)
 
int update_eci (cosmosstruc *root, double utc, cartpos pos)
 
void hardware_init_eci (cosmosstruc *cinfo, locstruc &loc)
 Initialize Hardware. More...
 
void gauss_jackson_setup (gj_handle &gjh, uint32_t order, double utc, double &dt)
 Prepare for Gauss-Jackson integration. More...
 
void gauss_jackson_init_tle (gj_handle &gjh, uint32_t order, int32_t mode, double dt, double mjd, cosmosstruc *cinfo)
 
void gauss_jackson_init_eci (gj_handle &gjh, uint32_t order, int32_t mode, double dt, double mjd, cartpos ipos, qatt iatt, physicsstruc &physics, locstruc &loc)
 Initialize Gauss-Jackson orbit using ECI state vector. More...
 
void gauss_jackson_init_stk (gj_handle &gjh, uint32_t order, int32_t mode, double dt, double mjd, stkstruc &stk, physicsstruc &physics, locstruc &loc)
 
void gauss_jackson_init (gj_handle &gjh, uint32_t order, int32_t mode, double dt, double mjd, double altitude, double angle, double hour, locstruc &iloc, physicsstruc &physics, locstruc &loc)
 
locstruc gauss_jackson_converge_orbit (gj_handle &gjh, physicsstruc &physics)
 
void gauss_jackson_converge_hardware (gj_handle &gjh, physicsstruc &physics)
 
vector< locstrucgauss_jackson_propagate (gj_handle &gjh, physicsstruc &physics, locstruc &loc, double mjd)
 
int orbit_propagate (cosmosstruc *root, double mjd)
 Load TLE's from file. More...
 
int orbit_init (int32_t mode, double dt, double mjd, string ofile, cosmosstruc *root)
 Initialize orbit from orbital data. More...
 

Detailed Description

Function Documentation

void pleph_ ( double  [],
long *  ,
long *  ,
double  [] 
)
void dpleph_ ( double  [],
long *  ,
long *  ,
double  [] 
)
rvector gravity_vector ( svector  pos,
int  model,
uint32_t  degree 
)
557 {
558  double gp, g0, gm;
559  locstruc tloc;
560  rvector gvec;
561 
562  // Calculate potential and geocentric equivalent of position
563  g0 = gravity_potential(pos.lambda,pos.phi,pos.r,model,degree);
564  tloc.pos.geos.s = pos;
565  pos_geos2geoc(&tloc);
566 
567  gvec = rv_zero();
568 
569  // Difference in X direction
570  tloc.pos.geoc.s.col[0] -= .5;
571  pos_geoc2geos(&tloc);
572  gm = gravity_potential(tloc.pos.geos.s.lambda,tloc.pos.geos.s.phi,tloc.pos.geos.s.r,model,degree);
573  tloc.pos.geoc.s.col[0] += 1.;
574  pos_geoc2geos(&tloc);
575  gp = gravity_potential(tloc.pos.geos.s.lambda,tloc.pos.geos.s.phi,tloc.pos.geos.s.r,model,degree);
576  gvec.col[0] = (gp-gm);
577  tloc.pos.geoc.s.col[0] -= .5;
578 
579  // Difference in Y direction
580  tloc.pos.geoc.s.col[1] -= .5;
581  pos_geoc2geos(&tloc);
582  gm = gravity_potential(tloc.pos.geos.s.lambda,tloc.pos.geos.s.phi,tloc.pos.geos.s.r,model,degree);
583  tloc.pos.geoc.s.col[1] += 1.;
584  pos_geoc2geos(&tloc);
585  gp = gravity_potential(tloc.pos.geos.s.lambda,tloc.pos.geos.s.phi,tloc.pos.geos.s.r,model,degree);
586  gvec.col[1] = (gp-gm);
587  tloc.pos.geoc.s.col[1] -= .5;
588 
589  // Difference in Z direction
590  tloc.pos.geoc.s.col[2] -= .5;
591  pos_geoc2geos(&tloc);
592  gm = gravity_potential(tloc.pos.geos.s.lambda,tloc.pos.geos.s.phi,tloc.pos.geos.s.r,model,degree);
593  tloc.pos.geoc.s.col[2] += 1.;
594  pos_geoc2geos(&tloc);
595  gp = gravity_potential(tloc.pos.geos.s.lambda,tloc.pos.geos.s.phi,tloc.pos.geos.s.r,model,degree);
596  gvec.col[2] = (gp-gm);
597  tloc.pos.geoc.s.col[2] -= .5;
598 
599  gvec = rv_normal(gvec);
600  gvec = rv_smult(g0,gvec);
601 
602  return (gvec);
603 }
svector s
Position vector.
Definition: convertdef.h:318
double lambda
E/W in radians.
Definition: vector.h:172
3 element generic row vector
Definition: vector.h:53
spherpos geos
Definition: convertdef.h:743
cartpos geoc
Definition: convertdef.h:739
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
rvector s
Location.
Definition: convertdef.h:163
__inline_double g0(double a, double *p)
Definition: nrlmsise-00.cpp:613
static uint16_t model
Definition: add_radio.cpp:19
double phi
N/S in radians.
Definition: vector.h:170
rvector rv_normal(rvector v)
Normalize row order vector.
Definition: vector.cpp:212
int32_t pos_geos2geoc(locstruc *loc)
Convert GEOS to GEOC.
Definition: convertlib.cpp:1047
double gravity_potential(double lambda, double phi, double r, int model, uint32_t degree)
Definition: physicslib.cpp:605
int32_t pos_geoc2geos(locstruc *loc)
Convert GEOC to GEOS.
Definition: convertlib.cpp:983
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
double col[3]
Definition: vector.h:55
double r
Radius in meters.
Definition: vector.h:174
Definition: convertdef.h:876
double gravity_potential ( double  lon,
double  lat,
double  r,
int  model,
uint32_t  degree 
)
606 {
607  uint32_t il, im;
608  double slat;
609  double v, v1, v2, vm, plg, ilon;
610  double clon[MAXDEGREE+1], slon[MAXDEGREE+1];
611 
612  // Load Params
614 
615  if (lambda < 0.)
616  lambda += D2PI;
617 
618  v = v1 = v2 = 0.;
619  slat = sin(phi);
620  ilon = 0.;
621  for (im=0; im<=degree; im++)
622  {
623  clon[im] = cos(ilon);
624  slon[im] = sin(ilon);
625  ilon += lambda;
626  if (ilon >= D2PI)
627  ilon -= D2PI;
628  }
629  for (il=2; il<=degree; il++)
630  {
631  vm = 0.;
632  for (im=0; im<=il; im++)
633  {
634  plg = nplgndr(il,im,slat);
635  vm += (coef[il][im][0]*clon[im] + coef[il][im][1]*slon[im]) * plg;
636  }
637  v += (il+1) * vm * pow((REARTHM/(r)),static_cast <double>(il));
638  }
639  v += 1;
640  v *= -GM / (r*r);
641 
642  return (v);
643 }
double nplgndr(uint32_t l, uint32_t m, double x)
Legendre polynomial.
Definition: physicslib.cpp:791
#define GM
SI Mass * Gravitational Constant for Earth.
Definition: convertdef.h:79
static uint16_t model
Definition: add_radio.cpp:19
static double coef[360+1][360+1][2]
Definition: physicslib.cpp:39
static double plg[4][9]
Definition: nrlmsise-00.cpp:99
#define REARTHM
SI Radius of Earth.
Definition: convertdef.h:60
const double D2PI
Double precision 2*PI.
Definition: math/constants.h:16
#define MAXDEGREE
Definition: physicslib.cpp:34
int32_t gravity_params(int model)
Gravitational model parameters.
Definition: physicslib.cpp:699
rvector gravity_accel ( posstruc  pos,
int  model,
uint32_t  degree 
)

Calculates geocentric acceleration vector from chosen model.

Calculates geocentric acceleration vector from chosen model.

Calculates a spherical harmonic expansion of the chosen model of indicated order and degree for the requested position. The result is returned as a geocentric vector calculated at the epoch.

Parameters
posa posstruc providing the position at the epoch
modelModel to use for coefficients
degreeOrder and degree to calculate
Returns
A rvector pointing toward the earth
See also
pgm2000a_coef.txt
66 {
67  uint32_t il, im;
68  // double dlat, dlon;
69  double tmult;
70  //double ratio, rratio, xratio, yratio, zratio, vc[MAXDEGREE+1][MAXDEGREE+1], wc[MAXDEGREE+1][MAXDEGREE+1];
71  double ratio, rratio, xratio, yratio, zratio;
72  rvector accel;
73  double fr;
74  //double dc[5][4], ds[5][4];
75  //static double co[5][4][2] = {{{-9999.}}};
76 
77  // Zero out vc and wc
78  memset(vc,0,sizeof(vc));
79  memset(wc,0,sizeof(wc));
80 
81  // Load Params
83 
84  /*
85 if (co[0][0][0] == -9999.)
86  {
87  for (il=0; il<5; il++)
88  {
89  for (im=0; im<4; im++)
90  {
91  co[il][im][0] = coef[il][im][0];
92  co[il][im][1] = coef[il][im][1];
93  }
94  }
95  }
96 
97 SolidTide(pos,dc,ds);
98 for (il=0; il<5; il++)
99  {
100  for (im=0; im<4; im++)
101  {
102  coef[il][im][0] = co[il][im][0] + dc[il][im];
103  coef[il][im][1] = co[il][im][1] + ds[il][im];
104  }
105  }
106 */
107 
108  // Calculate cartesian Legendre terms
109  vc[0][0] = REARTHM/pos.geos.s.r;
110  wc[0][0] = 0.;
111  ratio = vc[0][0] / pos.geos.s.r;
112  rratio = REARTHM * ratio;
113  xratio = pos.geoc.s.col[0] * ratio;
114  yratio = pos.geoc.s.col[1] * ratio;
115  zratio = pos.geoc.s.col[2] * ratio;
116  vc[1][0] = zratio * vc[0][0];
117  wc[1][0] = 0.;
118  for (il=2; il<=degree+1; il++)
119  {
120  vc[il][0] = (2*il-1)*zratio * vc[il-1][0] / il - (il-1) * rratio * vc[il-2][0] / il;
121  wc[il][0] = 0.;
122  }
123  for (im=1; im<=degree+1; im++)
124  {
125  vc[im][im] = (2*im-1) * (xratio * vc[im-1][im-1] - yratio * wc[im-1][im-1]);
126  wc[im][im] = (2*im-1) * (xratio * wc[im-1][im-1] + yratio * vc[im-1][im-1]);
127  if (im <= degree)
128  {
129  vc[im+1][im] = (2*im+1) * zratio * vc[im][im];
130  wc[im+1][im] = (2*im+1) * zratio * wc[im][im];
131  }
132  for (il=im+2; il<=degree+1; il++)
133  {
134  vc[il][im] = (2*il-1) * zratio * vc[il-1][im] / (il-im) - (il+im-1) * rratio * vc[il-2][im] / (il-im);
135  wc[il][im] = (2*il-1) * zratio * wc[il-1][im] / (il-im) - (il+im-1) * rratio * wc[il-2][im] / (il-im);
136  }
137  }
138 
139  // dr = dlon = dlat = 0.;
140 
141  accel = rv_zero();
142  for (im=0; im<=degree; im++)
143  {
144  for (il=im; il<=degree; il++)
145  {
146  if (im == 0)
147  {
148  accel.col[0] -= coef[il][0][0] * vc[il+1][1];
149  accel.col[1] -= coef[il][0][0] * wc[il+1][1];
150  accel.col[2] -= (il+1) * (coef[il][0][0] * vc[il+1][0]);
151  }
152  else
153  {
154  fr = ftl[il-im+2] / ftl[il-im];
155  accel.col[0] -= .5 * (coef[il][im][0] * vc[il+1][im+1] + coef[il][im][1] * wc[il+1][im+1] - fr * (coef[il][im][0] * vc[il+1][im-1] + coef[il][im][1] * wc[il+1][im-1]));
156  accel.col[1] -= .5 * (coef[il][im][0] * wc[il+1][im+1] - coef[il][im][1] * vc[il+1][im+1] + fr * (coef[il][im][0] * wc[il+1][im-1] - coef[il][im][1] * vc[il+1][im-1]));
157  accel.col[2] -= (il-im+1) * (coef[il][im][0] * vc[il+1][im] + coef[il][im][1] * wc[il+1][im]);
158  }
159  }
160  }
161  tmult = GM / (REARTHM*REARTHM);
162  accel.col[0] *= tmult;
163  accel.col[2] *= tmult;
164  accel.col[1] *= tmult;
165 
166  return (accel);
167 }
svector s
Position vector.
Definition: convertdef.h:318
static double wc[360+1][360+1]
Definition: physicslib.cpp:52
static double vc[360+1][360+1]
Data structures for spherical harmonic expansion.
Definition: physicslib.cpp:52
3 element generic row vector
Definition: vector.h:53
spherpos geos
Definition: convertdef.h:743
cartpos geoc
Definition: convertdef.h:739
#define GM
SI Mass * Gravitational Constant for Earth.
Definition: convertdef.h:79
rvector s
Location.
Definition: convertdef.h:163
static uint16_t model
Definition: add_radio.cpp:19
static double coef[360+1][360+1][2]
Definition: physicslib.cpp:39
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
#define REARTHM
SI Radius of Earth.
Definition: convertdef.h:60
double col[3]
Definition: vector.h:55
double r
Radius in meters.
Definition: vector.h:174
int32_t gravity_params(int model)
Gravitational model parameters.
Definition: physicslib.cpp:699
static double ftl[2 *360+1]
Definition: physicslib.cpp:37
rvector gravity_accel2 ( posstruc  pos,
int  model,
uint32_t  degree 
)

Calculates geocentric acceleration vector from chosen model.

646 {
647  uint32_t il, im;
648  double slat;
649  double v, v1, v2, vm, plg, ilon;
650  double clon[MAXDEGREE+1], slon[MAXDEGREE+1];
651  double radius, colat, elon;
652  rvector accel1;
653  locstruc sloc;
654 
655  // Load Params
657 
658  radius = pos.geos.s.r;
659  colat = pos.geod.s.lat;
660  colat = pos.geos.s.phi;
661  elon = pos.geod.s.lon;
662  elon = pos.geos.s.lambda;
663  if (elon < 0.)
664  elon += D2PI;
665 
666  v = v1 = v2 = 0.;
667  slat = sin(colat);
668  ilon = 0.;
669  for (im=0; im<=degree; im++)
670  {
671  clon[im] = cos(ilon);
672  slon[im] = sin(ilon);
673  ilon += elon;
674  if (ilon >= D2PI)
675  ilon -= D2PI;
676  }
677  for (il=2; il<=degree; il++)
678  {
679  vm = 0.;
680  for (im=0; im<=il; im++)
681  {
682  plg = nplgndr(il,im,slat);
683  vm += (coef[il][im][0]*clon[im] + coef[il][im][1]*slon[im]) * plg;
684  }
685  v += (il+1) * vm * pow((REARTHM/(radius)),(double)il);
686  }
687  v += 1;
688  v *= -GM / (radius*radius);
689 
690  sloc.pos = pos;
691  sloc.pos.geod.s.lat += .4448*(sloc.pos.geod.s.lat - sloc.pos.geos.s.phi);
692  pos_geod2geoc(&sloc);
693  accel1 = sloc.pos.geoc.s;
694  normalize_rv(accel1);
695  accel1 = rv_smult(v,accel1);
696  return (accel1);
697 }
svector s
Position vector.
Definition: convertdef.h:318
double lambda
E/W in radians.
Definition: vector.h:172
3 element generic row vector
Definition: vector.h:53
spherpos geos
Definition: convertdef.h:743
double nplgndr(uint32_t l, uint32_t m, double x)
Legendre polynomial.
Definition: physicslib.cpp:791
void normalize_rv(rvector &v)
Normalize row order vector in place.
Definition: vector.cpp:222
cartpos geoc
Definition: convertdef.h:739
#define GM
SI Mass * Gravitational Constant for Earth.
Definition: convertdef.h:79
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
rvector s
Location.
Definition: convertdef.h:163
static uint16_t model
Definition: add_radio.cpp:19
double phi
N/S in radians.
Definition: vector.h:170
static double coef[360+1][360+1][2]
Definition: physicslib.cpp:39
double lon
Longitude in radians.
Definition: vector.h:227
static double plg[4][9]
Definition: nrlmsise-00.cpp:99
int32_t pos_geod2geoc(locstruc *loc)
Update GEOD to GEOC in locstruc.
Definition: convertlib.cpp:1250
static locstruc sloc[MAXGJORDER+2]
Definition: physicslib.cpp:47
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
#define REARTHM
SI Radius of Earth.
Definition: convertdef.h:60
gvector s
Position vector.
Definition: convertdef.h:263
double lat
Latitude in radians.
Definition: vector.h:225
const double D2PI
Double precision 2*PI.
Definition: math/constants.h:16
geoidpos geod
Definition: convertdef.h:741
double r
Radius in meters.
Definition: vector.h:174
#define MAXDEGREE
Definition: physicslib.cpp:34
int32_t gravity_params(int model)
Gravitational model parameters.
Definition: physicslib.cpp:699
Definition: convertdef.h:876
double gravity ( double  radius,
double  colat,
double  elon,
int  model,
uint32_t  degree 
)

Calculates geocentric acceleration magnitude from chosen model.

int32_t gravity_params ( int  model)

Gravitational model parameters.

700 {
701  int32_t iretn;
702  uint32_t il, im;
703  double norm;
704  uint32_t dil, dim;
705  double dummy1, dummy2;
706 
707  // Calculate factorial
708  if (ftl[0] == 0.)
709  {
710  ftl[0] = 1.;
711  for (il=1; il<2*MAXDEGREE+1; il++)
712  {
713  ftl[il] = il * ftl[il-1];
714  }
715  }
716 
717  // Load Coefficients
718  if (cmodel != model)
719  {
720  coef[0][0][0] = 1.;
721  coef[0][0][1] = 0.;
722  coef[1][0][0] = coef[1][0][1] = 0.;
723  coef[1][1][0] = coef[1][1][1] = 0.;
724  string fname;
725  FILE *fi;
726  switch (model)
727  {
728  case GRAVITY_EGM2008:
730  iretn = get_cosmosresources(fname);
731  if (iretn < 0)
732  {
733  return iretn;
734  }
735  fname += "/general/egm2008_coef.txt";
736  fi = fopen(fname.c_str(),"r");
737 
738  if (fi==NULL)
739  {
740  cout << "could not load file " << fname << endl;
741  return iretn;
742  }
743 
744  for (il=2; il<101; il++)
745  {
746  for (im=0; im<= il; im++)
747  {
748  iretn = fscanf(fi,"%u %u %lf %lf\n",&dil,&dim,&coef[il][im][0],&coef[il][im][1]);
749  if (iretn && model == GRAVITY_EGM2008_NORM)
750  {
751  norm = sqrt(ftl[il+im]/((2-(im==0?1:0))*(2*il+1)*ftl[il-im]));
752  coef[il][im][0] /= norm;
753  coef[il][im][1] /= norm;
754  }
755  }
756  }
757  fclose(fi);
758  cmodel = model;
759  break;
760  case GRAVITY_PGM2000A:
762  default:
763  iretn = get_cosmosresources(fname);
764  if (iretn < 0)
765  {
766  return iretn;
767  }
768  fname += "/general/pgm2000a_coef.txt";
769  fi = fopen(fname.c_str(),"r");
770  for (il=2; il<361; il++)
771  {
772  for (im=0; im<= il; im++)
773  {
774  iretn = fscanf(fi,"%u %u %lf %lf %lf %lf\n",&dil,&dim,&coef[il][im][0],&coef[il][im][1],&dummy1,&dummy2);
775  if (iretn && model == GRAVITY_PGM2000A_NORM)
776  {
777  norm = sqrt(ftl[il+im]/((2-(il==im?1:0))*(2*il+1)*ftl[il-im]));
778  coef[il][im][0] /= norm;
779  coef[il][im][1] /= norm;
780  }
781  }
782  }
783  fclose(fi);
784  cmodel = model;
785  break;
786  }
787  }
788  return 0;
789 }
#define GRAVITY_EGM2008_NORM
Definition: physicsdef.h:70
int iretn
Definition: rw_test.cpp:37
#define GRAVITY_PGM2000A_NORM
Definition: physicsdef.h:69
string get_cosmosresources(bool create_flag)
Return COSMOS Resources Directory.
Definition: datalib.cpp:1337
static uint16_t model
Definition: add_radio.cpp:19
#define GRAVITY_EGM2008
Definition: physicsdef.h:68
static int cmodel
Definition: physicslib.cpp:38
static char fname[100]
Definition: geomag.cpp:89
static double coef[360+1][360+1][2]
Definition: physicslib.cpp:39
#define GRAVITY_PGM2000A
Definition: physicsdef.h:67
#define MAXDEGREE
Definition: physicslib.cpp:34
static double ftl[2 *360+1]
Definition: physicslib.cpp:37
double nplgndr ( uint32_t  l,
uint32_t  m,
double  x 
)

Legendre polynomial.

1821  {
1822  double fact,pll,pmm,pmmp1,omx2, oldfact;
1823  uint16_t i, ll, mm;
1824  static double lastx = 10.;
1825  static uint16_t lastm = 65535;
1826 
1827  pll = 0.;
1828  if (lastm == 65535 || m > lastm || x != lastx)
1829  {
1830  lastx = x;
1831  lastm = m;
1832  mm = m;
1833  // for (mm=0; mm<=maxdegree; mm++)
1834  // {
1835  pmm=1.0;
1836  if (mm > 0)
1837  {
1838  omx2=((1.0-x)*(1.0+x));
1839  fact=1.0;
1840  for (i=1;i<=mm;i++)
1841  {
1842  pmm *= fact*omx2/(fact+1.);
1843  fact += 2.0;
1844  }
1845  }
1846  pmm = sqrt((2.*m+1.)*pmm);
1847  if (mm%2 == 1)
1848  pmm = - pmm;
1849  spmm[mm] = pmm;
1850  // }
1851  }
1852 
1853  pmm = spmm[m];
1854  if (l == m)
1855  return pmm;
1856  else {
1857  pmmp1=x*sqrt(2.*m+3.)*pmm;
1858  if (l == (m+1))
1859  return pmmp1;
1860  else {
1861  oldfact = sqrt(2.*m+3.);
1862  for (ll=m+2;ll<=l;ll++)
1863  {
1864  fact = sqrt((4.*ll*ll-1.)/(ll*ll-m*m));
1865  pll=(x*pmmp1-pmm/oldfact)*fact;
1866  oldfact = fact;
1867  pmm=pmmp1;
1868  pmmp1=pll;
1869  }
1870  return pll;
1871  }
1872  }
1873  }
int i
Definition: rw_test.cpp:37
x
Definition: inputfile.py:6
static uint16_t lastm
Definition: physicslib.cpp:42
Definition: eci2kep_test.cpp:33
static double spmm[360+1]
Definition: physicslib.cpp:40
static double lastx
Definition: physicslib.cpp:41
svector groundstation ( locstruc satellite,
locstruc groundstation 
)

Ground station values.

Ground station values.

Calculates aziumth and elevation for each gound station in the list of ground stations for a satellite at the indicated position.

Parameters
satellitepointer to a locstruc specifying satellite position
groundstationpointer to a locstruc specifying groundstation to be targeted
Returns
svector containing azimuth in lambda, elevation in phi and slant range in r.
See also
geoc2topo
topo2azel
856 {
857  rvector topo;
858  svector azel = {0.,0.,0.};
859  float lambda, phi;
860 
861  pos_icrf2eci(&satellite);
862  pos_eci2geoc(&satellite);
863  geoc2topo(groundstation.pos.geod.s,satellite.pos.geoc.s,topo);
864  topo2azel(topo, lambda, phi);
865  azel.lambda = lambda;
866  azel.phi = phi;
867  azel.r = length_rv(topo);
868  return (azel);
869 }
double lambda
E/W in radians.
Definition: vector.h:172
3 element generic row vector
Definition: vector.h:53
double length_rv(rvector v)
Length of row vector.
Definition: vector.cpp:748
int32_t geoc2topo(gvector source, rvector targetgeoc, rvector &topo)
Geocentric to Topocentric.
Definition: convertlib.cpp:3033
cartpos geoc
Definition: convertdef.h:739
rvector s
Location.
Definition: convertdef.h:163
double phi
N/S in radians.
Definition: vector.h:170
3 element spherical vector
Definition: vector.h:167
int32_t pos_eci2geoc(locstruc *loc)
Convert ECI to GEOC.
Definition: convertlib.cpp:836
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
gvector s
Position vector.
Definition: convertdef.h:263
geoidpos geod
Definition: convertdef.h:741
double r
Radius in meters.
Definition: vector.h:174
int32_t topo2azel(rvector tpos, float &az, float &el)
Definition: convertlib.cpp:3129
int32_t pos_icrf2eci(locstruc *loc)
Convert Barycentric to ECI.
Definition: convertlib.cpp:626
void simulate_hardware ( cosmosstruc cinfo,
locstruc loc 
)

Simulate all devices.

Simulate all devices.

Simulate the behavior of all the hardware in the indicated satellite, at the indicated location, assuming a timestep of dt.

Parameters
cinfoReference to cosmosstruc to use.
locStructure specifying location

Calculate change in Angular Momentum and therefore Acceleration

Accelerate Reaction Wheel and calculate Component currents.

Component currents for each MTR

952 {
953  double speed, density, sattemp;
954  rvector vbody, vplanet;
955  double adrag, edot, sdot, vdot, ddrag;
956  double energy, efficiency, energyd, dcharge, dheat;
957  double sdheat;
958  rvector geov, vec;
959 // rvector unitv, units, unite, dtorque, da;
960  Vector unitv, units, unite, dtorque, da;
961  uint16_t i, j, index;
962  rmatrix mom;
963  // rmatrix tskew;
964  rvector mag_moment;
965  rvector mtorque, wtorque, wmomentum;
966  rvector bearth;
967  double tcexp, dalp, domg, dmom;
968  quaternion tq;
969 
970 
971  // Atmospheric and solar drag
972 // unitv = loc.pos.geoc.v;
973 // normalize_rv(unitv);
974 // unitv = irotate((loc.att.geoc.s),unitv);
975  unitv = Quaternion(loc.att.geoc.s).irotate(Vector(loc.pos.geoc.v).normalize());
976 
977 // units = rv_smult(-1.,loc.pos.icrf.s);
978 // normalize_rv(units);
979 // units = irotate((loc.att.icrf.s),units);
980  units = Quaternion(loc.att.icrf.s).irotate(Vector(loc.pos.icrf.s).normalize());
981 
982 // unite = rv_smult(-1.,loc.pos.eci.s);
983 // normalize_rv(unite);
984 // unite = irotate((loc.att.icrf.s),unite);
985  unite = Vector(loc.pos.eci.s).normalize(-1.);
986  unite = Vector(loc.pos.eci.s).normalize(-1.);
987  unite = Quaternion(loc.att.icrf.s).irotate(Vector(loc.pos.eci.s).normalize(-1.));
988 
989  geov = loc.pos.geoc.v;
990  speed = geov.col[0]*geov.col[0]+geov.col[1]*geov.col[1]+geov.col[2]*geov.col[2];
991  if (loc.pos.geod.s.h < 10000. || std::isnan(loc.pos.geod.s.h))
992  density = 1.225;
993  else
994  density = 1000. * msis00_density(loc.pos,150.,150.,3.);
995  // density = 0.;
996  adrag = density * 1.1 * speed;
997 
998  cinfo->node.phys.powgen = 0.;
999 
1000  cinfo->node.phys.atorque = cinfo->node.phys.rtorque = Vector();
1001  cinfo->node.phys.adrag = cinfo->node.phys.rdrag = Vector();
1002  sdheat = 0;
1003  sattemp = cinfo->node.phys.heat / (cinfo->node.phys.mass * cinfo->node.phys.hcap);
1004  for (i=0; i<cinfo->pieces.size(); i++)
1005  {
1006  cinfo->pieces[i].heat = cinfo->pieces[i].mass * cinfo->pieces[i].temp * cinfo->pieces[i].hcap;
1007  energyd = cinfo->node.phys.dt * SIGMA * pow(cinfo->pieces[i].temp,4);
1008  dheat = (cinfo->pieces[i].temp-sattemp)/100000.*cinfo->pieces[i].heat;
1009  cinfo->pieces[i].heat -= dheat;
1010  sdheat += dheat;
1011  dheat = cinfo->pieces[i].emi*cinfo->pieces[i].area * energyd;
1012  cinfo->pieces[i].heat -= dheat;
1013  sdheat += dheat;
1014 
1015  if (cinfo->pieces[i].face_cnt == 1)
1016  {
1017  cinfo->pieces[i].heat -= dheat;
1018 // vdot = dot_rv(unitv,cinfo->pieces[i].normal);
1019  vdot = unitv.dot(cinfo->faces[abs(cinfo->pieces[i].face_idx[0])].normal);
1020  if (vdot > 0)
1021  {
1022  if (cinfo->node.phys.mass)
1023  {
1024  ddrag = adrag*vdot/cinfo->node.phys.mass;
1025  }
1026  else
1027  {
1028  ddrag = 0.;
1029  }
1030  dtorque = ddrag * cinfo->pieces[i].twist;
1031  cinfo->node.phys.atorque += dtorque;
1032  da = ddrag * cinfo->pieces[i].shove;
1033  cinfo->node.phys.adrag += da;
1034  }
1035 
1036  sdot = units.dot(cinfo->faces[abs(cinfo->pieces[i].face_idx[0])].normal);
1037  if (loc.pos.sunradiance && sdot > 0)
1038  {
1039  ddrag = loc.pos.sunradiance * sdot / (3e8*cinfo->node.phys.mass);
1040  dtorque = ddrag * cinfo->pieces[i].twist;
1041  cinfo->node.phys.rtorque += dtorque;
1042  da = ddrag * cinfo->pieces[i].shove;
1043  cinfo->node.phys.rdrag += da;
1044 
1045  cinfo->pieces[i].insol = loc.pos.sunradiance * sdot / cinfo->faces[abs(cinfo->pieces[i].face_idx[0])].normal.norm();
1046  energyd = cinfo->pieces[i].insol * cinfo->node.phys.dt;
1047  cinfo->pieces[i].heat += cinfo->pieces[i].area * cinfo->pieces[i].abs * energyd;
1048  if (cinfo->pieces[i].cidx<(uint16_t)DeviceType::NONE && cinfo->device[cinfo->pieces[i].cidx].type == (uint16_t)DeviceType::PVSTRG)
1049  {
1050  j = cinfo->device[cinfo->pieces[i].cidx].didx;
1051  if (cinfo->device[cinfo->devspec.pvstrg[j]].pvstrg.effbase > 0.)
1052  {
1053  efficiency = cinfo->device[cinfo->devspec.pvstrg[j]].pvstrg.effbase + cinfo->device[cinfo->devspec.pvstrg[j]].pvstrg.effslope * cinfo->pieces[i].temp;
1054  cinfo->device[cinfo->devspec.pvstrg[j]].power = cinfo->pieces[i].area*efficiency*cinfo->pieces[i].insol;
1055  cinfo->device[cinfo->devspec.pvstrg[j]].volt = cinfo->device[cinfo->devspec.pvstrg[j]].nvolt;
1056  cinfo->device[cinfo->devspec.pvstrg[j]].amp = -cinfo->device[cinfo->devspec.pvstrg[j]].power / cinfo->device[cinfo->devspec.pvstrg[j]].volt;
1057  cinfo->node.phys.powgen += .4 * cinfo->device[cinfo->devspec.pvstrg[j]].power;
1058  cinfo->pieces[i].heat += (cinfo->pieces[i].abs * cinfo->pieces[i].area * cinfo->pieces[i].insol - cinfo->device[cinfo->devspec.pvstrg[j]].pvstrg.power) * cinfo->node.phys.dt;
1059  cinfo->pieces[i].heat -= cinfo->pieces[i].emi * cinfo->pieces[i].area * energyd;
1060  }
1061  }
1062  }
1063  else
1064  {
1065  for (j=0; j<cinfo->devspec.pvstrg_cnt; j++)
1066  {
1067  if (cinfo->device[cinfo->devspec.pvstrg[j]].pidx == i)
1068  {
1069  cinfo->device[cinfo->devspec.pvstrg[j]].power = 0.;
1070  cinfo->device[cinfo->devspec.pvstrg[j]].volt = 0.;
1071  cinfo->device[cinfo->devspec.pvstrg[j]].amp = 0.;
1072  cinfo->pieces[i].heat -= cinfo->pieces[i].emi * cinfo->pieces[i].area * energyd;
1073  }
1074  }
1075  }
1076  edot = acos(unite.dot(cinfo->faces[abs(cinfo->pieces[i].face_idx[0])].normal) / cinfo->faces[abs(cinfo->pieces[i].face_idx[0])].normal.norm()) - RADOF(5.);
1077  if (edot < 0.)
1078  edot = 1.;
1079  else
1080  edot = cos(edot);
1081  if (edot > 0)
1082  {
1083  energyd = edot * cinfo->node.phys.dt * SIGMA * pow(290.,4);
1084  cinfo->pieces[i].heat += cinfo->pieces[i].abs*cinfo->pieces[i].area * energyd;
1085  for (j=0; j<cinfo->devspec.pvstrg_cnt; j++)
1086  {
1087  if (cinfo->device[cinfo->devspec.pvstrg[j]].pidx == i)
1088  {
1089  energy += cinfo->pieces[i].abs * cinfo->pieces[i].area * energyd;
1090  }
1091  }
1092  }
1093  }
1094  }
1095 
1096  // Simulate devices
1097 
1098  cinfo->node.phys.ctorque = Vector();
1099  cinfo->node.phys.hmomentum = Vector();
1100  cinfo->node.phys.ctorque = cinfo->node.phys.ftorque;
1101 
1102  // Start with Reaction Wheel Torque
1103 
1104  for (i=0; i<cinfo->devspec.rw_cnt; i++)
1105  {
1107 
1108  // Moments of Reaction Wheel in Device frame
1109  mom = rm_diag(cinfo->device[cinfo->devspec.rw[i]].rw.mom);
1110 
1111  // Torque and Momentum from reaction wheel
1112 
1113  // Calculate Momentum in Body frame and transform to ICRF
1114  //tskew = rm_skew(loc.att.icrf.v);
1115 
1116  wmomentum = rv_mmult(mom,rv_smult(cinfo->device[cinfo->devspec.rw[i]].rw.omg,rv_unitz()));
1117  wmomentum = irotate(cinfo->device[cinfo->devspec.rw[i]].rw.align,wmomentum);
1118 // cinfo->node.phys.hmomentum = rv_add(cinfo->node.phys.hmomentum,wmomentum);
1119  cinfo->node.phys.hmomentum += Vector(wmomentum);
1120 
1121  // Calculate Torque in Body frame and transform to ICRF
1122  wtorque = rv_mmult(mom,rv_smult(cinfo->device[cinfo->devspec.rw[i]].rw.alp,rv_unitz()));
1123  wtorque = irotate(cinfo->device[cinfo->devspec.rw[i]].rw.align,wtorque);
1124 // cinfo->node.phys.ctorque = rv_sub(cinfo->node.phys.ctorque,wtorque);
1125  cinfo->node.phys.ctorque += Vector(wtorque);
1126 
1127  // Term for exponential change
1128  tcexp = exp(-cinfo->node.phys.dt/cinfo->device[cinfo->devspec.rw[i]].rw.tc);
1129 
1130  // Keep alpha within allowed limits
1131  if (cinfo->device[cinfo->devspec.rw[i]].rw.ralp > cinfo->device[cinfo->devspec.rw[i]].rw.mxalp)
1132  cinfo->device[cinfo->devspec.rw[i]].rw.ralp = cinfo->device[cinfo->devspec.rw[i]].rw.mxalp;
1133  if (cinfo->device[cinfo->devspec.rw[i]].rw.ralp < -cinfo->device[cinfo->devspec.rw[i]].rw.mxalp)
1134  cinfo->device[cinfo->devspec.rw[i]].rw.ralp = -cinfo->device[cinfo->devspec.rw[i]].rw.mxalp;
1135 
1136  // Set alpha to zero if accelerating past limit
1137  if (cinfo->device[cinfo->devspec.rw[i]].rw.omg < -cinfo->device[cinfo->devspec.rw[i]].rw.mxomg)
1138  {
1139  if (cinfo->device[cinfo->devspec.rw[i]].rw.ralp < 0.)
1140  cinfo->device[cinfo->devspec.rw[i]].rw.ralp = 0.;
1141  }
1142  if (cinfo->device[cinfo->devspec.rw[i]].rw.omg > cinfo->device[cinfo->devspec.rw[i]].rw.mxomg)
1143  {
1144  if (cinfo->device[cinfo->devspec.rw[i]].rw.ralp > 0.)
1145  cinfo->device[cinfo->devspec.rw[i]].rw.ralp = 0.;
1146  }
1147 
1148  // Calculate change in acceleration effects
1149  if (cinfo->device[cinfo->devspec.rw[i]].rw.ralp != cinfo->device[cinfo->devspec.rw[i]].rw.alp)
1150  {
1151  dalp = tcexp * (cinfo->device[cinfo->devspec.rw[i]].rw.alp - cinfo->device[cinfo->devspec.rw[i]].rw.ralp);
1152  cinfo->device[cinfo->devspec.rw[i]].rw.alp = cinfo->device[cinfo->devspec.rw[i]].rw.ralp + dalp;
1153  domg = -cinfo->device[cinfo->devspec.rw[i]].rw.tc * dalp;
1154  }
1155  else
1156  domg = 0.;
1157 
1159  cinfo->device[cinfo->devspec.rw[i]].rw.omg += cinfo->node.phys.dt * cinfo->device[cinfo->devspec.rw[i]].rw.alp + domg;
1160  cinfo->device[cinfo->device[cinfo->devspec.rw[i]].cidx].amp = .054 * fabs(cinfo->device[cinfo->devspec.rw[i]].rw.omg)/400. + .093 * fabs(cinfo->device[cinfo->devspec.rw[i]].rw.alp) / 30.;
1161  cinfo->device[cinfo->devspec.rw[i]].utc = loc.utc;
1162  }
1163 
1164  // Determine magtorquer moments in body frame
1165  // Magtorquer Torque is Cross Product of B field and Moments
1166  mtorque = rv_zero();
1167  mag_moment = rv_zero();
1168  for (i=0; i<cinfo->devspec.mtr_cnt; i++)
1169  {
1170  // Magnetic Moments in Body frame
1171  mag_moment = rv_add(mag_moment,irotate(cinfo->device[cinfo->devspec.mtr[i]].mtr.align,rv_smult(cinfo->device[cinfo->devspec.mtr[i]].mtr.mom,rv_unitz())));
1172 
1173  tcexp = exp(-cinfo->node.phys.dt/cinfo->device[cinfo->devspec.mtr[i]].mtr.tc);
1174 
1175  // Keep field within allowed limits
1176  if (cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom > cinfo->device[cinfo->devspec.mtr[i]].mtr.mxmom)
1177  cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom = cinfo->device[cinfo->devspec.mtr[i]].mtr.mxmom;
1178  if (cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom < -cinfo->device[cinfo->devspec.mtr[i]].mtr.mxmom)
1179  cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom = -cinfo->device[cinfo->devspec.mtr[i]].mtr.mxmom;
1180 
1181  if (cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom != cinfo->device[cinfo->devspec.mtr[i]].mtr.mom)
1182  {
1183  dmom = tcexp * (cinfo->device[cinfo->devspec.mtr[i]].mtr.mom - cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom);
1184  cinfo->device[cinfo->devspec.mtr[i]].mtr.mom = cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom + dmom;
1185  }
1186 
1188  if (cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom < 0.)
1189  {
1190  cinfo->device[cinfo->device[cinfo->devspec.mtr[i]].cidx].amp = cinfo->device[cinfo->devspec.mtr[i]].mtr.mom * (3.6519e-3 - cinfo->device[cinfo->devspec.mtr[i]].mtr.mom * 8.6439e-5);
1191  }
1192  else
1193  {
1194  cinfo->device[cinfo->device[cinfo->devspec.mtr[i]].cidx].amp = cinfo->device[cinfo->devspec.mtr[i]].mtr.mom * (3.6519e-3 + cinfo->device[cinfo->devspec.mtr[i]].mtr.mom * 8.6439e-5);
1195  }
1196  // cinfo->device[cinfo->devspec.mtr[i]].mtr.mom = cinfo->device[cinfo->device[cinfo->devspec.mtr[i]].cidx].amp*(229.43-cinfo->device[cinfo->device[cinfo->devspec.mtr[i]].cidx].amp*382.65);
1197 
1198  cinfo->device[cinfo->devspec.mtr[i]].utc = loc.utc;
1199  }
1200 
1201  // Get magnetic field in body frame
1202  bearth = irotate(loc.att.geoc.s,loc.pos.bearth);
1203 
1204  mtorque = rv_cross(mag_moment,bearth);
1205  // mtorque = irotate(q_conjugate(loc.att.icrf.s),mtorque);
1206 // cinfo->node.phys.ctorque = rv_add(cinfo->node.phys.ctorque,mtorque);
1207  cinfo->node.phys.ctorque += Vector(mtorque);
1208 
1209  // Star Trackers
1210  for (i=0; i<cinfo->devspec.stt_cnt; i++)
1211  {
1212  cinfo->device[cinfo->devspec.stt[i]].utc = loc.utc;
1213  tq = q_fmult(q_conjugate(cinfo->device[cinfo->devspec.stt[i]].stt.align),loc.att.icrf.s);
1214  cinfo->device[cinfo->devspec.stt[i]].stt.att = tq;
1215  cinfo->device[cinfo->devspec.stt[i]].stt.omega = irotate(tq,loc.att.icrf.v);
1216  cinfo->device[cinfo->devspec.stt[i]].utc = loc.utc;
1217  }
1218 
1219  // Inertial Measurement Units
1220  for (i=0; i<cinfo->devspec.imu_cnt; i++)
1221  {
1222  // convert attitude from ICRF to sensor body frame
1223  // att.s = 0th order derivative (quaternion)
1224  // embbed into a function
1225  // 'updates' cinfo->devspec.imu[i] with noise modified data
1226  simulate_imu(i, cinfo, loc);
1227  cinfo->device[cinfo->devspec.imu[i]].utc = loc.utc;
1228  }
1229 
1230  for (i=0; i<cinfo->devspec.gps_cnt; i++)
1231  {
1232  cinfo->device[cinfo->devspec.gps[i]].utc = loc.utc;
1233  cinfo->device[cinfo->devspec.gps[i]].gps.geocs = loc.pos.geoc.s;
1234  cinfo->device[cinfo->devspec.gps[i]].gps.dgeocs = rv_one(5., 5., 5.);
1235  cinfo->device[cinfo->devspec.gps[i]].gps.geocv = loc.pos.geoc.v;
1236  cinfo->device[cinfo->devspec.gps[i]].gps.dgeocv = rv_one();
1237  }
1238 
1239  for (i=0; i<cinfo->devspec.ssen_cnt; i++)
1240  {
1241  // Get sun vector in body frame
1242  vec = irotate(loc.att.icrf.s,rv_smult(-1.,loc.pos.icrf.s));
1243  // Rotate into sun sensor frame
1244  vec = irotate(q_conjugate(cinfo->device[cinfo->devspec.ssen[i]].ssen.align),vec);
1245  // Convert this to az and el
1246  topo2azel(vec, cinfo->device[cinfo->devspec.ssen[i]].ssen.azimuth, cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1247  if (cinfo->device[cinfo->devspec.ssen[i]].ssen.azimuth < 0.)
1248  {
1249  cinfo->device[cinfo->devspec.ssen[i]].ssen.azimuth += D2PI;
1250  }
1251  cinfo->device[cinfo->devspec.ssen[i]].ssen.qva = cinfo->device[cinfo->devspec.ssen[i]].ssen.qvb = cinfo->device[cinfo->devspec.ssen[i]].ssen.qvc = cinfo->device[cinfo->devspec.ssen[i]].ssen.qvd = 0.;
1252  if (cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation > RADOF(70.))
1253  {
1254  cinfo->device[cinfo->devspec.ssen[i]].ssen.qva = cinfo->device[cinfo->devspec.ssen[i]].ssen.qvb = cinfo->device[cinfo->devspec.ssen[i]].ssen.qvc = cinfo->device[cinfo->devspec.ssen[i]].ssen.qvd = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1255  }
1256  else
1257  {
1258  if (cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation > RADOF(30.))
1259  {
1260  switch ((int)(cinfo->device[cinfo->devspec.ssen[i]].ssen.azimuth/(DPI/4.)+.5))
1261  {
1262  case 0:
1263  cinfo->device[cinfo->devspec.ssen[i]].ssen.qva = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1264  break;
1265  case 1:
1266  cinfo->device[cinfo->devspec.ssen[i]].ssen.qva = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1267  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvb = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1268  break;
1269  case 2:
1270  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvb = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1271  break;
1272  case 3:
1273  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvb = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1274  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvc = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1275  break;
1276  case 4:
1277  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvc = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1278  break;
1279  case 5:
1280  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvc = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1281  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvd = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1282  break;
1283  case 6:
1284  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvd = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1285  break;
1286  case 7:
1287  cinfo->device[cinfo->devspec.ssen[i]].ssen.qvd = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1288  cinfo->device[cinfo->devspec.ssen[i]].ssen.qva = sin(cinfo->device[cinfo->devspec.ssen[i]].ssen.elevation);
1289  break;
1290  }
1291  }
1292  }
1293  cinfo->device[cinfo->devspec.ssen[i]].utc = loc.utc;
1294  }
1295 
1296  // Simulate thsters
1297  for (i=0; i<cinfo->devspec.thst_cnt; i++)
1298  {
1299 // cinfo->device[cinfo->devspec.thst[i]].thst.flw = (length_rv(cinfo->node.phys.thrust) / cinfo->devspec.thst_cnt) / cinfo->device[cinfo->devspec.thst[i]].thst.isp;
1300  cinfo->device[cinfo->devspec.thst[i]].thst.flw = (cinfo->node.phys.thrust.norm() / cinfo->devspec.thst_cnt) / cinfo->device[cinfo->devspec.thst[i]].thst.isp;
1301  if (cinfo->device[cinfo->devspec.thst[i]].thst.flw < .002)
1302  cinfo->device[cinfo->devspec.thst[i]].thst.flw = 0.;
1303  cinfo->device[cinfo->devspec.prop[i]].prop.lev -= cinfo->node.phys.dt * cinfo->device[cinfo->devspec.thst[i]].thst.flw;
1304  cinfo->device[cinfo->devspec.thst[i]].utc = loc.utc;
1305  }
1306 
1307  // Simulate drive motors
1308  vbody = rv_zero();
1309  for (i=0; i<cinfo->devspec.motr_cnt; i++)
1310  {
1311  cinfo->device[cinfo->device[cinfo->devspec.motr[i]].cidx].amp = cinfo->device[cinfo->devspec.motr[i]].motr.spd;
1312  vbody = rv_add(vbody,rv_smult(cinfo->device[cinfo->devspec.motr[i]].motr.spd*cinfo->device[cinfo->devspec.motr[i]].motr.rat,rv_unitx()));
1313  if (i == cinfo->devspec.motr_cnt-1)
1314  {
1315  switch (loc.pos.extra.closest)
1316  {
1317  case COSMOS_EARTH:
1318  vplanet = irotate(q_conjugate(loc.att.geoc.s),vbody);
1319  loc.pos.geoc.s = rv_add(loc.pos.geoc.s,vplanet);
1320  break;
1321  case COSMOS_MOON:
1322  vplanet = irotate(q_conjugate(loc.att.selc.s),vbody);
1323  loc.pos.selc.s = rv_add(loc.pos.selc.s,vplanet);
1324  break;
1325  }
1326  }
1327  cinfo->device[cinfo->devspec.motr[i]].utc = loc.utc;
1328  }
1329 
1330  // Disk drive details
1331  for (i=0; i<cinfo->devspec.pload_cnt; i++)
1332  {
1333  if (cinfo->device[cinfo->devspec.pload[i]].flag&DEVICE_FLAG_ON && cinfo->device[cinfo->devspec.pload[i]].drate != 0.)
1334  {
1335  cinfo->device[cinfo->devspec.disk[0]].disk.gib += cinfo->device[cinfo->devspec.pload[i]].drate;
1336  }
1337  }
1338 
1339  // Power details
1340  cinfo->node.phys.powuse = 0.;
1341  for (i=0; i<cinfo->devspec.bus_cnt; i++)
1342  {
1343  cinfo->device[cinfo->devspec.bus[i]].amp = 0.;
1344  }
1345 
1346  for (i=0; i<cinfo->node.device_cnt; i++)
1347  {
1348  index = cinfo->device[i].bidx;
1349  if (index >= cinfo->devspec.bus_cnt)
1350  {
1351  index = 0;
1352  }
1353  if (cinfo->devspec.bus_cnt && cinfo->device[i].flag&DEVICE_FLAG_ON && cinfo->device[cinfo->devspec.bus[index]].flag&DEVICE_FLAG_ON)
1354  {
1355  cinfo->device[i].power = cinfo->device[i].amp * cinfo->device[i].volt;
1356  cinfo->device[cinfo->devspec.bus[index]].amp += cinfo->device[i].amp;
1357  if (cinfo->device[i].volt > cinfo->device[cinfo->devspec.bus[index]].volt)
1358  {
1359  cinfo->device[cinfo->devspec.bus[index]].volt = cinfo->device[i].volt;
1360  }
1361  if (cinfo->device[i].power <= 0.)
1362  continue;
1363  if (cinfo->device[i].pidx < cinfo->node.piece_cnt)
1364  {
1365  cinfo->pieces[cinfo->device[i].pidx].heat += .8 * cinfo->device[i].power * cinfo->node.phys.dt;
1366  }
1367  if (cinfo->device[i].type != (uint16_t)DeviceType::BUS)
1368  {
1369  cinfo->node.phys.powuse += cinfo->device[i].power;
1370  }
1371  }
1372  else
1373  {
1374  cinfo->device[i].power = 0.;
1375  }
1376  }
1377 
1378  // Heat details
1379  cinfo->node.phys.heat = 0.;
1380  for (i=0; i<cinfo->pieces.size(); i++)
1381  {
1382  if (cinfo->node.phys.mass)
1383  {
1384  cinfo->pieces[i].heat += sdheat*cinfo->pieces[i].mass/cinfo->node.phys.mass;
1385  // cinfo->pieces[i].heat += sdheat/cinfo->pieces.size();
1386  cinfo->node.phys.heat += cinfo->pieces[i].heat;
1387  cinfo->pieces[i].temp = cinfo->pieces[i].heat / (cinfo->pieces[i].mass * cinfo->pieces[i].hcap);
1388  if (cinfo->pieces[i].cidx < cinfo->device.size())
1389  {
1390  cinfo->device[cinfo->pieces[i].cidx].temp = cinfo->pieces[i].temp;
1391  }
1392  }
1393  else
1394  {
1395  cinfo->pieces[i].temp = 0.;
1396  }
1397  }
1398 
1399  for (i=0; i<cinfo->devspec.tsen_cnt; i++)
1400  {
1401  cinfo->device[cinfo->devspec.tsen[i]].temp = cinfo->pieces[cinfo->device[cinfo->device[cinfo->devspec.tsen[i]].cidx].pidx].temp;
1402  cinfo->device[cinfo->devspec.tsen[i]].utc = loc.utc;
1403  }
1404 
1405  // More Power details
1406  if (cinfo->devspec.batt_cnt)
1407  {
1408  dcharge = (cinfo->node.phys.dt/3600.) * ((cinfo->node.phys.powgen-cinfo->node.phys.powuse) / cinfo->device[cinfo->devspec.batt[0]].volt) / cinfo->devspec.batt_cnt;
1409  }
1410  else
1411  {
1412  dcharge = 0.;
1413  }
1414  for (i=0; i<cinfo->devspec.batt_cnt; i++)
1415  {
1416  cinfo->device[cinfo->devspec.batt[i]].batt.charge += dcharge;
1417  cinfo->node.phys.battlev += dcharge;
1418  if (cinfo->device[cinfo->devspec.batt[i]].batt.charge > cinfo->device[cinfo->devspec.batt[i]].batt.capacity)
1419  cinfo->device[cinfo->devspec.batt[i]].batt.charge = cinfo->device[cinfo->devspec.batt[i]].batt.capacity;
1420  if (cinfo->device[cinfo->devspec.batt[i]].batt.charge < 0.)
1421  cinfo->device[cinfo->devspec.batt[i]].batt.charge = 0.;
1422  cinfo->device[cinfo->devspec.batt[i]].utc = loc.utc;
1423  }
1424 
1425  if (cinfo->node.phys.powgen > cinfo->node.phys.powuse)
1426  cinfo->node.flags |= NODE_FLAG_CHARGING;
1427  else
1428  cinfo->node.flags &= ~NODE_FLAG_CHARGING;
1429 
1430  if (cinfo->node.phys.battlev < 0.)
1431  cinfo->node.phys.battlev = 0.;
1432 
1433  if (cinfo->node.phys.battlev >= cinfo->node.phys.battcap)
1434  {
1435  cinfo->node.flags &= ~NODE_FLAG_CHARGING;
1436  cinfo->node.phys.battlev = cinfo->node.phys.battcap;
1437  }
1438 
1439 
1440  cinfo->timestamp = currentmjd();
1441 }
rvector bearth
Earth magnetic vector in ITRS for this time and location.
Definition: convertdef.h:754
Photo Voltaic String.
Definition: jsondef.h:514
double timestamp
Timestamp for last change to data.
Definition: jsondef.h:4202
uint16_t imu_cnt
Definition: jsondef.h:3871
vector< uint16_t > mtr
Definition: jsondef.h:3907
vector< facestruc > faces
Vector of all faces in node.
Definition: jsondef.h:4229
vector< uint16_t > stt
Definition: jsondef.h:3916
uint16_t device_cnt
Definition: jsondef.h:3571
qatt geoc
Definition: convertdef.h:828
vector< uint16_t > prop
Definition: jsondef.h:3909
double dot(Vector b)
Dot product.
Definition: vector.cpp:1684
rvector rv_add(rvector a, rvector b)
Add two row vectors.
Definition: vector.cpp:299
Definition: cosmos-defs.h:114
vector< uint16_t > bus
Definition: jsondef.h:3898
Vector adrag
Definition: jsondef.h:3445
vector< uint16_t > gps
Definition: jsondef.h:3902
double norm()
Norm.
Definition: vector.cpp:1735
3 element generic row vector
Definition: vector.h:53
uint16_t tsen_cnt
Definition: jsondef.h:3891
int i
Definition: rw_test.cpp:37
Vector thrust
Definition: jsondef.h:3447
cartpos selc
Definition: convertdef.h:740
float battcap
Definition: jsondef.h:3430
uint16_t motr_cnt
Definition: jsondef.h:3873
uint16_t ssen_cnt
Definition: jsondef.h:3882
Quaternion, scalar last, using x, y, z.
Definition: vector.h:402
float battlev
Definition: jsondef.h:3431
quaternion q_conjugate(quaternion q)
Definition: vector.cpp:1010
Not a Component.
Definition: jsondef.h:556
uint16_t piece_cnt
Definition: jsondef.h:3570
cartpos geoc
Definition: convertdef.h:739
Vector ftorque
Definition: jsondef.h:3437
vector< uint16_t > imu
Definition: jsondef.h:3904
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
vector< uint16_t > rw
Definition: jsondef.h:3913
#define DEVICE_FLAG_ON
Definition: jsondef.h:634
uint16_t pload_cnt
Definition: jsondef.h:3875
float sunradiance
Watts per square meter per steradian.
Definition: convertdef.h:752
rvector rv_one()
Row vector of ones.
Definition: vector.cpp:151
uint16_t closest
Definition: convertdef.h:607
vector< uint16_t > pload
Definition: jsondef.h:3908
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
uint16_t flags
Definition: jsondef.h:3579
quaternion q_fmult(rvector r1, quaternion q2)
rvector quaternion multiply
Definition: vector.cpp:1079
vector< devicestruc > device
Vector of all general (common) information for devices (components) in node.
Definition: jsondef.h:4238
nodestruc node
Structure for summary information in node.
Definition: jsondef.h:4220
rvector s
Location.
Definition: convertdef.h:163
float hcap
Definition: jsondef.h:3424
attstruc att
attstruc for this time.
Definition: convertdef.h:883
uint16_t pvstrg_cnt
Definition: jsondef.h:3883
uint16_t gps_cnt
Definition: jsondef.h:3869
uint16_t batt_cnt
Definition: jsondef.h:3864
qatt selc
Definition: convertdef.h:829
3x3 element generic matrix
Definition: matrix.h:41
vector< uint16_t > disk
Definition: jsondef.h:3901
Vector rtorque
Definition: jsondef.h:3439
vector< uint16_t > motr
Definition: jsondef.h:3906
uint16_t bus_cnt
Definition: jsondef.h:3865
rmatrix rm_diag(rvector a)
Diagonal rmatrix Creates an rmatrix whose diagonal is filled with the supplied rvector.
Definition: matrix.cpp:97
qatt icrf
Definition: convertdef.h:830
Vector rdrag
Definition: jsondef.h:3446
vector< uint16_t > thst
Definition: jsondef.h:3922
double h
Height in meters.
Definition: vector.h:229
Vector ctorque
Definition: jsondef.h:3443
extrapos extra
Definition: convertdef.h:744
Vector atorque
Definition: jsondef.h:3438
Vector hmomentum
Definition: jsondef.h:3442
rvector rv_unitz(double scale)
Scaled z row vector.
Definition: vector.cpp:140
uint16_t rw_cnt
Definition: jsondef.h:3880
vector< uint16_t > tsen
Definition: jsondef.h:3924
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
float powuse
Definition: jsondef.h:3433
Power Bus.
Definition: jsondef.h:538
#define COSMOS_MOON
Definition: convertdef.h:144
#define COSMOS_EARTH
Definition: convertdef.h:137
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
float heat
Definition: jsondef.h:3427
gvector s
Position vector.
Definition: convertdef.h:263
Vector & normalize(double size=1.)
Normalize.
Definition: vector.cpp:1706
float mass
Definition: jsondef.h:3425
const double D2PI
Double precision 2*PI.
Definition: math/constants.h:16
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
double msis00_density(posstruc pos, float f107avg, float f107, float magidx)
Calculate atmospheric density.
Definition: physicslib.cpp:1664
vector< piecestruc > pieces
Vector of all pieces in node.
Definition: jsondef.h:4232
double col[3]
Definition: vector.h:55
float speed
Definition: netperf_send.cpp:40
double dt
Time step in seconds.
Definition: jsondef.h:3414
rvector irotate(quaternion q, rvector v)
Indirectly rotate a row vector using a quaternion.
Definition: mathlib.cpp:2308
cartpos eci
Definition: convertdef.h:737
uint16_t thst_cnt
Definition: jsondef.h:3890
geoidpos geod
Definition: convertdef.h:741
int32_t topo2azel(rvector tpos, float &az, float &el)
Definition: convertlib.cpp:3129
void simulate_imu(int index, cosmosstruc *cinfo, locstruc &loc)
Simulate IMU.
Definition: physicslib.cpp:1467
devspecstruc devspec
Structure for devices (components) special data in node, by type.
Definition: jsondef.h:4241
Vector Class.
Definition: vector.h:672
const double DPI
Double precision PI.
Definition: math/constants.h:14
#define SIGMA
SI Stefan-Boltzmann constant.
Definition: convertdef.h:51
cartpos icrf
Definition: convertdef.h:736
uint16_t mtr_cnt
Definition: jsondef.h:3874
rvector rv_unitx(double scale)
Scaled x row vector.
Definition: vector.cpp:118
rvector rv_mmult(rmatrix m, rvector v)
Multiply rmatrix by rvector.
Definition: matrix.cpp:41
vector< uint16_t > batt
Definition: jsondef.h:3896
rvector rv_cross(rvector a, rvector b)
Take cross product of two row vectors.
Definition: vector.cpp:363
Vector irotate(const Vector &v)
Indirectly rotate a ::Vector using a ::Quaternion.
Definition: vector.cpp:2473
physicsstruc phys
Definition: jsondef.h:3597
float powgen
Definition: jsondef.h:3432
vector< uint16_t > pvstrg
Definition: jsondef.h:3911
rvector v
Velocity.
Definition: convertdef.h:165
uint16_t stt_cnt
Definition: jsondef.h:3884
vector< uint16_t > ssen
Definition: jsondef.h:3915
#define RADOF(deg)
Radians of a Degree value.
Definition: math/constants.h:29
void simulate_hardware ( cosmosstruc cinfo,
vector< locstruc > &  locvec 
)

Simulate Hardware data - multiple.

Simulate the behavior of all the hardware in the indicated satellite, for each indicated location in the array.

Parameters
cinfoReference to cosmosstruc to use.
locvecArray of locstruc specifying locations.
938 {
939  for (size_t i=0; i<locvec.size(); ++i)
940  {
941  simulate_hardware(cinfo, locvec[i]);
942  }
943 }
int i
Definition: rw_test.cpp:37
void simulate_hardware(cosmosstruc *cinfo, vector< locstruc > &locvec)
Simulate Hardware data - multiple.
Definition: physicslib.cpp:937
void initialize_imu ( uint16_t  index,
devspecstruc devspec,
locstruc loc 
)

Initialize IMU simulation.

Initialize IMU simulation.

Set the indicated IMU to a base attitude and position. Use the logic that the current attitude and position are equivalent to the origin of the position frame and the identity attitude. Set all velocities and accelerations to zero.

Parameters
indexIndex of desired IMU.
devspecPointer to structure holding specs on imu.
locStructure specifying location
1453 {
1454  if (index >= devspec.imu_cnt)
1455  return;
1456 
1457 }
uint16_t imu_cnt
Definition: jsondef.h:3871
void simulate_imu ( int  index,
cosmosstruc cinfo,
locstruc loc 
)

Simulated IMU values.

Simulated IMU values.

Turn the current attitude into likely values for the indicated IMU. Inject any likely noise due to the nature of the IMU.

Parameters
indexWhich IMU to use.
cinfoReference to cosmosstruc to use.
locStructure specifying location
indexIndex of desired IMU.

Set time of reading

Set raw values for accelerometer and gyros

Set magnetic field in IMU frame

1468 {
1469  quaternion toimu;
1470 
1471  if (index >= cinfo->devspec.imu_cnt)
1472  return;
1473 
1474  toimu = q_fmult(q_conjugate(cinfo->device[cinfo->devspec.imu[index]].imu.align),loc.att.icrf.s);
1476  cinfo->device[cinfo->devspec.imu[index]].utc = loc.utc;
1477 
1479  cinfo->device[cinfo->devspec.imu[index]].imu.accel = irotate(toimu,loc.pos.icrf.a);
1480  cinfo->device[cinfo->devspec.imu[index]].imu.omega = irotate(toimu,loc.att.icrf.v);
1481 
1483  cinfo->device[cinfo->devspec.imu[index]].imu.mag = irotate(q_conjugate(cinfo->device[cinfo->devspec.imu[index]].imu.align),irotate(loc.att.geoc.s,loc.pos.bearth));
1484 
1485  cinfo->timestamp = currentmjd();
1486 }
rvector bearth
Earth magnetic vector in ITRS for this time and location.
Definition: convertdef.h:754
double timestamp
Timestamp for last change to data.
Definition: jsondef.h:4202
uint16_t imu_cnt
Definition: jsondef.h:3871
qatt geoc
Definition: convertdef.h:828
rvector a
Acceleration.
Definition: convertdef.h:167
Quaternion, scalar last, using x, y, z.
Definition: vector.h:402
quaternion q_conjugate(quaternion q)
Definition: vector.cpp:1010
vector< uint16_t > imu
Definition: jsondef.h:3904
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
quaternion q_fmult(rvector r1, quaternion q2)
rvector quaternion multiply
Definition: vector.cpp:1079
vector< devicestruc > device
Vector of all general (common) information for devices (components) in node.
Definition: jsondef.h:4238
attstruc att
attstruc for this time.
Definition: convertdef.h:883
qatt icrf
Definition: convertdef.h:830
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
rvector irotate(quaternion q, rvector v)
Indirectly rotate a row vector using a quaternion.
Definition: mathlib.cpp:2308
devspecstruc devspec
Structure for devices (components) special data in node, by type.
Definition: jsondef.h:4241
cartpos icrf
Definition: convertdef.h:736
int32_t pos_accel ( physicsstruc physics,
locstruc loc 
)

Acceleration.

Acceleration.

Calculate the linear forces on the specified sattelite at the specified location/

Parameters
physicsPointer to structure specifying satellite.
locStructure specifying location.
1554 {
1555  int32_t iretn;
1556  double radius;
1557  rvector ctpos, da, tda;
1558  cartpos bodypos;
1559 
1560  radius = length_rv(loc.pos.eci.s);
1561 
1562  loc.pos.eci.a = rv_zero();
1563 
1564  // Earth gravity
1565  // Calculate Geocentric acceleration vector
1566 
1567  if (radius > REARTHM)
1568  {
1569  // Start with gravity vector in ITRS
1570 
1571  da = gravity_accel(loc.pos,GRAVITY_EGM2008_NORM,12);
1572 
1573  // Correct for earth rotation, polar motion, precession, nutation
1574 
1575  da = rv_mmult(loc.pos.extra.e2j,da);
1576  }
1577  else
1578  {
1579  // Simple 2 body
1580  da = rv_smult(-GM/(radius*radius*radius),loc.pos.eci.s);
1581  }
1582  loc.pos.eci.a = rv_add(loc.pos.eci.a,da);
1583 
1584  // Sun gravity
1585  // Calculate Satellite to Sun vector
1586  ctpos = rv_sub(rv_smult(-1.,loc.pos.extra.sun2earth.s),loc.pos.eci.s);
1587  radius = length_rv(ctpos);
1588  da = rv_smult(GSUN/(radius*radius*radius),ctpos);
1589  loc.pos.eci.a = rv_add(loc.pos.eci.a,da);
1590 
1591  // Adjust for acceleration of frame
1592  radius = length_rv(loc.pos.extra.sun2earth.s);
1593  da = rv_smult(GSUN/(radius*radius*radius),loc.pos.extra.sun2earth.s);
1594  tda = da;
1595  loc.pos.eci.a = rv_add(loc.pos.eci.a,da);
1596 
1597  // Moon gravity
1598  // Calculate Satellite to Moon vector
1599  bodypos.s = rv_sub(loc.pos.extra.sun2earth.s,loc.pos.extra.sun2moon.s);
1600  ctpos = rv_sub(bodypos.s,loc.pos.eci.s);
1601  radius = length_rv(ctpos);
1602  da = rv_smult(GMOON/(radius*radius*radius),ctpos);
1603  loc.pos.eci.a = rv_add(loc.pos.eci.a,da);
1604 
1605  // Adjust for acceleration of frame due to moon
1606  radius = length_rv(bodypos.s);
1607  da = rv_smult(GMOON/(radius*radius*radius),bodypos.s);
1608  tda = rv_sub(tda,da);
1609  loc.pos.eci.a = rv_sub(loc.pos.eci.a,da);
1610 
1611  /*
1612 // Jupiter gravity
1613 // Calculate Satellite to Jupiter vector
1614 jplpos(JPL_EARTH,JPL_JUPITER,loc.pos.extra.tt,(cartpos *)&bodypos);
1615 ctpos = rv_sub(bodypos.s,loc.pos.eci.s);
1616 radius = length_rv(ctpos);
1617 
1618 // Calculate acceleration
1619 da = rv_smult(GJUPITER/(radius*radius*radius),ctpos);
1620 //loc.pos.eci.a = rv_add(loc.pos.eci.a,da);
1621 */
1622 
1623  // Atmospheric drag
1624  if (length_rv(physics.adrag.to_rv()))
1625  {
1626  da = irotate(q_conjugate(loc.att.icrf.s),physics.adrag.to_rv());
1627  loc.pos.eci.a = rv_add(loc.pos.eci.a,da);
1628  }
1629  // Solar drag
1630  if (length_rv(physics.rdrag.to_rv()))
1631  {
1632  da = irotate(q_conjugate(loc.att.icrf.s),physics.rdrag.to_rv());
1633  loc.pos.eci.a = rv_add(loc.pos.eci.a,da);
1634  }
1635  // Fictitious drag
1636  if (length_rv(physics.fdrag.to_rv()))
1637  {
1638  da = irotate(q_conjugate(loc.att.icrf.s),physics.fdrag.to_rv());
1639  loc.pos.eci.a = rv_add(loc.pos.eci.a,da);
1640  }
1641 
1642  loc.pos.eci.pass++;
1643  iretn = pos_eci(&loc);
1644  if (iretn < 0)
1645  {
1646  return iretn;
1647  }
1648  if (std::isnan(loc.pos.eci.a.col[0]))
1649  {
1650  loc.pos.eci.a.col[0] = 0.;
1651  }
1652  return 0;
1653 }
Vector fdrag
Definition: jsondef.h:3444
#define GRAVITY_EGM2008_NORM
Definition: physicsdef.h:70
cartpos sun2earth
Definition: convertdef.h:605
rvector rv_add(rvector a, rvector b)
Add two row vectors.
Definition: vector.cpp:299
Vector adrag
Definition: jsondef.h:3445
3 element generic row vector
Definition: vector.h:53
rvector a
Acceleration.
Definition: convertdef.h:167
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
Cartesian full position structure.
Definition: convertdef.h:158
double length_rv(rvector v)
Length of row vector.
Definition: vector.cpp:748
quaternion q_conjugate(quaternion q)
Definition: vector.cpp:1010
int iretn
Definition: rw_test.cpp:37
rvector to_rv()
Convert from cvector.
Definition: vector.cpp:1638
cartpos sun2moon
Definition: convertdef.h:606
rvector gravity_accel(posstruc pos, int model, uint32_t degree)
Spherical harmonic gravitational vector.
Definition: physicslib.cpp:65
#define GM
SI Mass * Gravitational Constant for Earth.
Definition: convertdef.h:79
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
rvector s
Location.
Definition: convertdef.h:163
attstruc att
attstruc for this time.
Definition: convertdef.h:883
Definition: convertdef.h:568
qatt icrf
Definition: convertdef.h:830
Vector rdrag
Definition: jsondef.h:3446
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
extrapos extra
Definition: convertdef.h:744
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
#define GMOON
SI Mass * Gravitational Constant for Moon.
Definition: convertdef.h:81
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
#define REARTHM
SI Radius of Earth.
Definition: convertdef.h:60
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
double col[3]
Definition: vector.h:55
rvector irotate(quaternion q, rvector v)
Indirectly rotate a row vector using a quaternion.
Definition: mathlib.cpp:2308
cartpos eci
Definition: convertdef.h:737
rmatrix e2j
Transform from Geocentric to ICRF.
Definition: convertdef.h:594
rvector rv_sub(rvector a, rvector b)
Subtract two vectors.
Definition: vector.cpp:315
rvector rv_mmult(rmatrix m, rvector v)
Multiply rmatrix by rvector.
Definition: matrix.cpp:41
#define GSUN
SI Mass * Gravitational Constant for Sun.
Definition: convertdef.h:83
void att_accel ( physicsstruc physics,
locstruc loc 
)

Torque.

Torque.

Calculate the torque forces on the specified satellite at the specified location/

Parameters
physicsPointer to structure specifying satellite.
locStructure specifying location.
1494 {
1495 // rvector ue, ta, tv;
1496 // rvector ttorque;
1497  Vector ue, ta, tv;
1498  Vector ttorque;
1499  rmatrix mom;
1500 
1501  att_extra(&loc);
1502 
1503  ttorque = physics.ctorque;
1504 
1505  // Now calculate Gravity Gradient Torque
1506  // Unit vector towards earth, rotated into body frame
1507 // ue = irotate((loc.att.icrf.s),rv_smult(-1.,loc.pos.eci.s));
1508 // normalize_rv(ue);
1509  ue = Quaternion(loc.att.icrf.s).irotate(-1. * Vector(loc.pos.eci.s)).normalize();
1510 
1511 // physics.gtorque = rv_smult((3.*GM/pow(loc.pos.geos.s.r,3.)),rv_cross(ue,rv_mult(physics.moi,ue)));
1512  physics.gtorque = (3. * GM / pow(loc.pos.geos.s.r,3.)) * ue.cross(physics.moi * ue);
1513 
1514 // ttorque = rv_add(ttorque,physics.gtorque);
1515  ttorque += physics.gtorque;
1516 
1517  // Atmospheric and solar torque
1518  // ttorque = rv_add(ttorque,physics.atorque);
1519  // ttorque = rv_add(ttorque,physics.rtorque);
1520 
1521  // Torque from rotational effects
1522 
1523  // Moment of Inertia in Body frame
1524  mom = rm_diag(physics.moi.to_rv());
1525  // Attitude rate in Body frame
1526  tv = irotate(loc.att.icrf.s,loc.att.icrf.v);
1527 
1528  // Torque from cross product of angular velocity and angular momentum
1529 // physics.htorque = rv_smult(-1., rv_cross(tv,rv_add(rv_mmult(mom,tv),physics.hmomentum)));
1530 // ttorque = rv_add(ttorque,physics.htorque);
1531  physics.htorque = -1. * tv.cross(Vector(rv_mmult(mom, tv.to_rv())) + physics.hmomentum);
1532  ttorque += physics.htorque;
1533 
1534  // Convert torque into accelerations, doing math in Body frame
1535 
1536  // I x alpha = tau, so alpha = I inverse x tau
1537 // ta = rv_mmult(rm_inverse(mom),ttorque);
1538  ta = Vector(rv_mmult(rm_inverse(mom),ttorque.to_rv()));
1539 
1540  // Convert body frame acceleration back to other frames.
1541  loc.att.icrf.a = irotate(q_conjugate(loc.att.icrf.s), ta.to_rv());
1542  loc.att.topo.a = irotate(q_conjugate(loc.att.topo.s), ta.to_rv());
1543  loc.att.lvlh.a = irotate(q_conjugate(loc.att.lvlh.s), ta.to_rv());
1544  loc.att.geoc.a = irotate(q_conjugate(loc.att.geoc.s), ta.to_rv());
1545  loc.att.selc.a = irotate(q_conjugate(loc.att.selc.s), ta.to_rv());
1546 }
Vector moi
Definition: jsondef.h:3448
svector s
Position vector.
Definition: convertdef.h:318
qatt geoc
Definition: convertdef.h:828
Definition: eci2kep_test.cpp:33
Vector gtorque
Definition: jsondef.h:3440
spherpos geos
Definition: convertdef.h:743
rvector a
2nd derivative: Alpha - acceleration
Definition: convertdef.h:483
quaternion q_conjugate(quaternion q)
Definition: vector.cpp:1010
Vector cross(Vector b)
Cross product.
Definition: vector.cpp:1667
rvector to_rv()
Convert from cvector.
Definition: vector.cpp:1638
qatt lvlh
Definition: convertdef.h:827
#define GM
SI Mass * Gravitational Constant for Earth.
Definition: convertdef.h:79
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
int32_t att_extra(locstruc *loc)
Calculate Extra attitude information.
Definition: convertlib.cpp:1572
rvector s
Location.
Definition: convertdef.h:163
attstruc att
attstruc for this time.
Definition: convertdef.h:883
rmatrix rm_inverse(rmatrix m)
Inverse of rmatrix.
Definition: matrix.cpp:897
Vector htorque
Definition: jsondef.h:3441
qatt selc
Definition: convertdef.h:829
3x3 element generic matrix
Definition: matrix.h:41
rmatrix rm_diag(rvector a)
Diagonal rmatrix Creates an rmatrix whose diagonal is filled with the supplied rvector.
Definition: matrix.cpp:97
qatt icrf
Definition: convertdef.h:830
Vector ctorque
Definition: jsondef.h:3443
Vector hmomentum
Definition: jsondef.h:3442
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
Vector & normalize(double size=1.)
Normalize.
Definition: vector.cpp:1706
qatt topo
Definition: convertdef.h:826
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
rvector irotate(quaternion q, rvector v)
Indirectly rotate a row vector using a quaternion.
Definition: mathlib.cpp:2308
cartpos eci
Definition: convertdef.h:737
double r
Radius in meters.
Definition: vector.h:174
Vector Class.
Definition: vector.h:672
rvector rv_mmult(rmatrix m, rvector v)
Multiply rmatrix by rvector.
Definition: matrix.cpp:41
Vector irotate(const Vector &v)
Indirectly rotate a ::Vector using a ::Quaternion.
Definition: vector.cpp:2473
void geod2icrf ( posstruc pos)

Geodetic to Heliocentric.

double msis86_density ( posstruc  pos,
float  f107avg,
float  f107,
float  magidx 
)
double msis00_density ( posstruc  pos,
float  f107avg,
float  f107,
float  magidx 
)

Calculate atmospheric density.

Calculate atmospheric density at indicated Latitute/Longitude/Altitude using the NRLMSISE-00 atmospheric model.

Parameters
posStructure indicating position
f107avgAverage 10.7 cm solar flux
f107Current 10.7 cm solar flux
magidxAp daily geomagnetic index
Returns
Density in kg/m3
1665 {
1666  struct nrlmsise_output output;
1667  struct nrlmsise_input input;
1668  struct nrlmsise_flags flags = {
1669  {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
1670  {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
1671  {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}};
1672  int year, month;
1673  double day, doy;
1674  static double lastmjd = 0.;
1675  static double lastdensity = 0.;
1676  static double lastperiod = 0.;
1677 
1678  if (lastperiod != 0.)
1679  {
1680  if (fabs(lastperiod) > (pos.extra.utc-lastmjd))
1681  {
1682  return (lastdensity*(1.+(.001*(pos.extra.utc-lastmjd)/lastperiod)));
1683  }
1684  }
1685 
1686  mjd2ymd(pos.extra.utc,year,month,day,doy);
1687  input.doy = (int32_t)doy;
1688  input.g_lat = pos.geod.s.lat*180./DPI;
1689  input.g_long = pos.geod.s.lon*180./DPI;
1690  input.alt = pos.geod.s.h / 1000.;
1691  input.sec = (doy - input.doy)*86400.;;
1692  input.lst = input.sec / 3600. + input.g_long / 15.;
1693  input.f107A = f107avg;
1694  input.f107 = f107;
1695  input.ap = magidx;
1696  gtd7d(&input,&flags,&output);
1697 
1698  if (lastdensity != 0. && lastdensity != output.d[5])
1699  lastperiod = (pos.extra.utc-lastmjd)*.001*output.d[5]/(output.d[5]-lastdensity);
1700  lastmjd = pos.extra.utc;
1701  lastdensity = output.d[5];
1702  return((double)output.d[5]);
1703 }
string output
Definition: agent-2-0.cpp:56
double utc
Coordinated Universal Time.
Definition: convertdef.h:582
void gtd7d(struct nrlmsise_input *input, struct nrlmsise_flags *flags, struct nrlmsise_output *output)
Definition: nrlmsise-00.cpp:1097
Definition: nrlmsise-00.h:172
int32_t mjd2ymd(double mjd, int32_t &year, int32_t &month, double &day)
MJD to Year, Month, and Decimal Day (overloaded)
Definition: timelib.cpp:217
double h
Height in meters.
Definition: vector.h:229
extrapos extra
Definition: convertdef.h:744
double lon
Longitude in radians.
Definition: vector.h:227
gvector s
Position vector.
Definition: convertdef.h:263
double lat
Latitude in radians.
Definition: vector.h:225
geoidpos geod
Definition: convertdef.h:741
const double DPI
Double precision PI.
Definition: math/constants.h:14
Definition: nrlmsise-00.h:132
Definition: nrlmsise-00.h:72
void orbit_init_tle ( int32_t  mode,
double  dt,
double  mjd,
cosmosstruc root 
)
1706 {
1707 
1708  uint16_t i;
1709 
1710  // Munge time step to fit local granularity
1711  dt = 86400.*((utc + dt/86400.)-utc);
1712 
1713  cinfo->node.phys.dt = dt;
1714  cinfo->node.phys.dtj = cinfo->node.phys.dt/86400.;
1715  cinfo->node.phys.mode = mode;
1716 
1717  locstruc loc;
1718  pos_clear(loc);
1719 
1720  lines2eci(utc,cinfo->tle,loc.pos.eci);
1721  loc.pos.eci.pass++;
1722  pos_eci(&loc);
1723 
1724  // Initial attitude
1725  cinfo->node.phys.ftorque = rv_zero();
1726  switch (cinfo->node.phys.mode)
1727  {
1728  //case 0:
1729  // loc.att.icrf.utc = loc.utc;
1730  // loc.att.icrf.s = q_eye();
1731  // loc.att.icrf.v = loc.att.icrf.a = rv_zero();
1732  // att_icrf(&loc);
1733  // break;
1734  case 1:
1735  loc.att.lvlh.utc = loc.utc;
1736  loc.att.lvlh.s = q_eye();
1737  loc.att.lvlh.v = rv_zero();
1738  att_lvlh2icrf(&loc);
1739  break;
1740  case 2:
1741  loc.att.lvlh.utc = loc.utc;
1742  loc.att.lvlh.s = q_change_around_y(-DPI2);
1743  loc.att.lvlh.v = rv_zero();
1744  att_lvlh2icrf(&loc);
1745  break;
1746  case 3:
1747  case 4:
1748  case 5:
1749  case 6:
1750  case 7:
1751  case 8:
1752  case 9:
1753  case 10:
1754  case 11:
1755  case 12:
1756  loc.att.icrf.s = q_drotate_between_rv(cinfo->faces[abs(cinfo->pieces[cinfo->node.phys.mode-2].face_idx[0])].normal.to_rv(),rv_smult(-1.,loc.pos.icrf.s));
1757  // loc.att.icrf.s = rm_change_between_rv(cinfo->pieces[cinfo->node.phys.mode-2].normal,rv_smult(-1.,loc.pos.icrf.s));
1758  loc.att.icrf.v = rv_zero();
1759  att_icrf2lvlh(&loc);
1760  break;
1761  }
1762 
1763 
1764  pos_accel(cinfo->node.phys, loc);
1765  // Initialize hardware,
1766  // ?? is this only for simulation?
1767  hardware_init_eci(cinfo,loc);
1768 
1769  // ?? check
1770  att_accel(cinfo->node.phys, loc);
1771  // groundstations(cinfo,&loc);
1772 
1773  sloc[0] = loc;
1774 
1775  // Position at t0-dt
1776  for (i=1; i<4; i++)
1777  {
1778  sloc[i] = sloc[i-1];
1779  sloc[i].utc -= dt / 86400.;
1780  lines2eci(sloc[i].utc,cinfo->tle,sloc[i].pos.eci);
1781  sloc[i].pos.eci.pass++;
1782  pos_eci(&sloc[i]);
1783 
1784  sloc[i].att.lvlh = sloc[i-1].att.lvlh;
1785  att_lvlh2icrf(&sloc[i]);
1786 
1787  // Initialize hardware
1788  pos_accel(cinfo->node.phys, sloc[i]);
1789  simulate_hardware(cinfo, sloc[i]);
1790  att_accel(cinfo->node.phys, sloc[i]);
1791  }
1792  cinfo->node.phys.utc = loc.utc;
1793 
1794  cinfo->timestamp = currentmjd();
1795 }
ElapsedTime dt
Definition: agent_file3.cpp:183
int i
Definition: rw_test.cpp:37
void simulate_hardware(cosmosstruc *cinfo, vector< locstruc > &locvec)
Simulate Hardware data - multiple.
Definition: physicslib.cpp:937
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
const double DPI2
Double precision PI/2.
Definition: math/constants.h:18
qatt lvlh
Definition: convertdef.h:827
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
quaternion q_change_around_y(double angle)
Rotation quaternion for Y axis.
Definition: vector.cpp:1435
double utc
Definition: convertdef.h:477
int32_t pos_clear(locstruc *loc)
Initialize posstruc.
Definition: convertlib.cpp:77
rvector s
Location.
Definition: convertdef.h:163
quaternion q_drotate_between_rv(rvector from, rvector to)
Create rotation quaternion from 2 row vectors.
Definition: mathlib.cpp:81
attstruc att
attstruc for this time.
Definition: convertdef.h:883
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
qatt icrf
Definition: convertdef.h:830
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
static locstruc sloc[MAXGJORDER+2]
Definition: physicslib.cpp:47
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
void hardware_init_eci(cosmosstruc *cinfo, locstruc &loc)
Initialize Hardware.
Definition: physicslib.cpp:877
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
cartpos eci
Definition: convertdef.h:737
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
cartpos icrf
Definition: convertdef.h:736
Definition: convertdef.h:876
int lines2eci(double utc, vector< tlestruc >lines, cartpos &eci)
Return position from TLE set.
Definition: convertlib.cpp:3155
int32_t pos_accel(physicsstruc &physics, locstruc &loc)
Position acceleration.
Definition: physicslib.cpp:1553
void orbit_init_eci ( int32_t  mode,
double  dt,
double  mjd,
cartpos  ipos,
cosmosstruc root 
)
1798 {
1799  kepstruc kep;
1800  double dea;
1801  uint16_t i;
1802 
1803  // Munge time step to fit local granularity
1804  dt = 86400.*((utc + dt/86400.)-utc);
1805 
1806  cinfo->node.phys.dt = dt;
1807  cinfo->node.phys.dtj = cinfo->node.phys.dt/86400.;
1808  cinfo->node.phys.mode = mode;
1809 
1810  locstruc loc;
1811  pos_clear(loc);
1812 
1813  loc.pos.eci = ipos;
1814  loc.utc = loc.att.icrf.utc = utc;
1815  loc.pos.eci.pass++;
1816  pos_eci(&loc);
1817  eci2kep(loc.pos.eci,kep);
1818 
1819  // Initial attitude
1820  cinfo->node.phys.ftorque = rv_zero();
1821  switch (cinfo->node.phys.mode)
1822  {
1823  //case 0:
1824  // loc.att.icrf.utc = loc.utc;
1825  // loc.att.icrf.s = q_eye();
1826  // loc.att.icrf.v = loc.att.icrf.a = rv_zero();
1827  // att_icrf(&loc);
1828  // break;
1829  case 1:
1830  loc.att.lvlh.utc = loc.utc;
1831  loc.att.lvlh.s = q_eye();
1832  loc.att.lvlh.v = rv_zero();
1833  att_lvlh2icrf(&loc);
1834  break;
1835  case 2:
1836  loc.att.lvlh.utc = loc.utc;
1837  loc.att.lvlh.s = q_change_around_y(-DPI2);
1838  loc.att.lvlh.v = rv_zero();
1839  att_lvlh2icrf(&loc);
1840  break;
1841  case 3:
1842  case 4:
1843  case 5:
1844  case 6:
1845  case 7:
1846  case 8:
1847  case 9:
1848  case 10:
1849  case 11:
1850  case 12:
1851  loc.att.icrf.s = q_drotate_between_rv(cinfo->faces[abs(cinfo->pieces[cinfo->node.phys.mode-2].face_idx[0])].normal.to_rv(),rv_smult(-1.,loc.pos.icrf.s));
1852  // loc.att.icrf.s = rm_change_between_rv(cinfo->pieces[cinfo->node.phys.mode-2].normal,rv_smult(-1.,loc.pos.icrf.s));
1853  loc.att.icrf.v = rv_zero();
1854  att_icrf2lvlh(&loc);
1855  break;
1856  }
1857 
1858 
1859  // groundstations(cinfo,&loc);
1860  pos_accel(cinfo->node.phys, loc);
1861  // Initialize hardware
1862  hardware_init_eci(cinfo, loc);
1863  att_accel(cinfo->node.phys, loc);
1864 
1865  sloc[0] = loc;
1866 
1867  // Position at t0-dt
1868  for (i=1; i<4; i++)
1869  {
1870  sloc[i] = sloc[i-1];
1871  sloc[i].utc -= dt / 86400.;
1872  kep.ma -= dt * kep.mm;
1873 
1874  uint16_t count = 0;
1875  do
1876  {
1877  dea = (kep.ea - kep.e * sin(kep.ea) - kep.ma) / (1. - kep.e * cos(kep.ea));
1878  kep.ea -= dea;
1879  } while (++count < 100 && fabs(dea) > .000001);
1880  kep2eci(kep,sloc[i].pos.eci);
1881  sloc[i].pos.eci.pass++;
1882  pos_eci(&sloc[i]);
1883 
1884  sloc[i].att.lvlh = sloc[i-1].att.lvlh;
1885  att_lvlh2icrf(&sloc[i]);
1886 
1887 
1888  pos_accel(cinfo->node.phys, sloc[i]);
1889  simulate_hardware(cinfo, sloc[i]);
1890  att_accel(cinfo->node.phys, sloc[i]);
1891  }
1892  cinfo->node.phys.utc = loc.utc;
1893 
1894  cinfo->timestamp = currentmjd();
1895 }
int32_t eci2kep(cartpos &eci, kepstruc &kep)
Definition: convertlib.cpp:2934
double mm
Mean Motion.
Definition: convertdef.h:561
ElapsedTime dt
Definition: agent_file3.cpp:183
int i
Definition: rw_test.cpp:37
double e
Eccentricity.
Definition: convertdef.h:540
int count
Definition: rw_test.cpp:36
void simulate_hardware(cosmosstruc *cinfo, vector< locstruc > &locvec)
Simulate Hardware data - multiple.
Definition: physicslib.cpp:937
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
double ma
Mean Anomoly.
Definition: convertdef.h:555
int32_t kep2eci(kepstruc &kep, cartpos &eci)
Definition: convertlib.cpp:2878
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
const double DPI2
Double precision PI/2.
Definition: math/constants.h:18
qatt lvlh
Definition: convertdef.h:827
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
quaternion q_change_around_y(double angle)
Rotation quaternion for Y axis.
Definition: vector.cpp:1435
double utc
Definition: convertdef.h:477
int32_t pos_clear(locstruc *loc)
Initialize posstruc.
Definition: convertlib.cpp:77
rvector s
Location.
Definition: convertdef.h:163
quaternion q_drotate_between_rv(rvector from, rvector to)
Create rotation quaternion from 2 row vectors.
Definition: mathlib.cpp:81
attstruc att
attstruc for this time.
Definition: convertdef.h:883
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
qatt icrf
Definition: convertdef.h:830
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
Classical elements structure.
Definition: convertdef.h:529
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
static locstruc sloc[MAXGJORDER+2]
Definition: physicslib.cpp:47
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
void hardware_init_eci(cosmosstruc *cinfo, locstruc &loc)
Initialize Hardware.
Definition: physicslib.cpp:877
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
cartpos eci
Definition: convertdef.h:737
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
cartpos icrf
Definition: convertdef.h:736
double ea
Eccentric Anomoly.
Definition: convertdef.h:559
Definition: convertdef.h:876
int32_t pos_accel(physicsstruc &physics, locstruc &loc)
Position acceleration.
Definition: physicslib.cpp:1553
void orbit_init_shape ( int32_t  mode,
double  dt,
double  mjd,
double  altitude,
double  angle,
double  hour,
cosmosstruc root 
)
1898 {
1899  double lon;
1900 
1901  lon = 2. * DPI * (fabs(hour)/24. - (utc - (int)utc));
1902 
1903  // Munge time step to fit local granularity
1904  dt = 86400.*((utc + dt/86400.)-utc);
1905 
1906  cinfo->node.phys.dt = dt;
1907  cinfo->node.phys.dtj = cinfo->node.phys.dt/86400.;
1908  cinfo->node.phys.mode = mode;
1909  initialutc = utc;
1910 
1911  locstruc loc;
1912  pos_clear(loc);
1913 
1914  // Initial position
1915  sloc[0] = sloc[1] = sloc[2] = loc;
1916  sloc[0].pos.geod.utc = sloc[0].att.geoc.utc = utc;
1917  sloc[0].pos.geod.s.h = altitude;
1918  sloc[0].pos.geos.s.r = rearth(0.) + altitude;
1919  sloc[0].pos.geod.s.lat = 0.;
1920  sloc[0].pos.geod.s.lon = lon;
1921  sloc[0].pos.geod.v.lat = sin(angle) * sqrt(GM/sloc[0].pos.geos.s.r) / sloc[0].pos.geos.s.r;
1922  sloc[0].pos.geod.v.h = 0.;
1923  sloc[0].pos.geod.v.lon = cos(angle) * sqrt(GM/sloc[0].pos.geos.s.r) / sloc[0].pos.geos.s.r;
1924  if (hour < 0)
1925  {
1926  sloc[0].pos.geod.v.lat = -sloc[0].pos.geod.v.lat;
1927  sloc[0].pos.geod.v.lon = -sloc[0].pos.geod.v.lon;
1928  }
1929  sloc[0].pos.geod.v.lon -= DPI / 43200.;
1930  sloc[0].pos.geod.pass++;
1931  pos_geod(&sloc[0]);
1932 
1933  // Initial attitude
1934  cinfo->node.phys.ftorque = rv_zero();
1935  switch (cinfo->node.phys.mode)
1936  {
1937  case 0:
1938  sloc[0].att.icrf.utc =sloc[0].utc;
1939  sloc[0].att.icrf.s = q_eye();
1940  sloc[0].att.icrf.v = loc.att.icrf.a = rv_zero();
1941  att_icrf2lvlh(&sloc[0]);
1942  break;
1943  case 1:
1944  sloc[0].att.lvlh.utc = sloc[0].utc;
1945  sloc[0].att.lvlh.s = q_eye();
1946  sloc[0].att.lvlh.v = rv_zero();
1947  att_lvlh2icrf(&sloc[0]);
1948  break;
1949  case 2:
1950  sloc[0].att.lvlh.utc =sloc[0].utc;
1952  sloc[0].att.lvlh.v = rv_zero();
1953  att_lvlh2icrf(&sloc[0]);
1954  break;
1955  case 3:
1956  case 4:
1957  case 5:
1958  case 6:
1959  case 7:
1960  case 8:
1961  case 9:
1962  case 10:
1963  case 11:
1964  case 12:
1965  sloc[0].att.icrf.s = q_drotate_between_rv(cinfo->faces[abs(cinfo->pieces[cinfo->node.phys.mode-2].face_idx[0])].normal.to_rv(),rv_smult(-1.,sloc[0].pos.icrf.s));
1966  // sloc[0].att.icrf.s = rm_change_between_rv(cinfo->pieces[cinfo->node.phys.mode-2].normal,rv_smult(-1.,loc.pos.icrf.s));
1967  sloc[0].att.icrf.v = rv_zero();
1968  att_icrf2lvlh(&sloc[0]);
1969  break;
1970  }
1971 
1972  // groundstations(cinfo,&sloc[0]);
1973  pos_accel(cinfo->node.phys, sloc[0]);
1974  // Initialize hardware
1975  hardware_init_eci(cinfo, sloc[0]);
1976  att_accel(cinfo->node.phys, sloc[0]);
1977 
1978  loc = sloc[0];
1979 
1980  // Position at t0-dt
1981  sloc[1].pos.geod.utc = sloc[1].att.geoc.utc = sloc[0].pos.geod.utc - dt/86400.;
1982  sloc[1].pos.geod.s.lat = sloc[0].pos.geod.s.lat - dt * sloc[0].pos.geod.v.lat;
1983  sloc[1].pos.geod.v.lat = sloc[0].pos.geod.v.lat;
1984  sloc[1].pos.geod.s.lon = sloc[0].pos.geod.s.lon - dt * sloc[0].pos.geod.v.lon;
1985  sloc[1].pos.geod.v.lon = (sloc[0].pos.geod.v.lon + DPI / 43200.) * cos(sloc[0].pos.geod.s.lat) / cos(sloc[1].pos.geod.s.lat) - DPI / 43200.;
1986  sloc[1].pos.geod.s.h = sloc[0].pos.geos.s.r - rearth(sloc[1].pos.geod.s.lat);
1987  sloc[1].pos.geod.v.h = (sloc[0].pos.geod.s.h - sloc[1].pos.geod.s.h) / dt;
1988  pos_geod(&sloc[1]);
1989 
1990  // Attitude at t0-dt
1991  sloc[1].att.lvlh = sloc[0].att.lvlh;
1992  att_lvlh2icrf(&sloc[1]);
1993 
1994  cinfo->node.phys.battlev = cinfo->node.phys.battcap;
1995 
1996  pos_accel(cinfo->node.phys, sloc[1]);
1997  simulate_hardware(cinfo, sloc[1]);
1998  att_accel(cinfo->node.phys, sloc[1]);
1999 
2000  // Position at t0-2*dt
2001  sloc[2].pos.geod.utc = sloc[2].att.geoc.utc = sloc[1].utc - dt/86400.;
2002  sloc[2].pos.geod.s.lat = sloc[1].pos.geod.s.lat - dt * sloc[1].pos.geod.v.lat;
2003  sloc[2].pos.geod.v.lat = sloc[1].pos.geod.v.lat;
2004  sloc[2].pos.geod.s.lon = sloc[1].pos.geod.s.lon - dt * sloc[1].pos.geod.v.lon;
2005  sloc[2].pos.geod.v.lon = (sloc[1].pos.geod.v.lon + DPI / 43200.) * cos(sloc[1].pos.geod.s.lat) / cos(sloc[2].pos.geod.s.lat) - DPI / 43200.;
2006  sloc[2].pos.geod.s.h = sloc[1].pos.geos.s.r - rearth(sloc[2].pos.geod.s.lat);
2007  sloc[2].pos.geod.v.h = (sloc[1].pos.geod.s.h - sloc[2].pos.geod.s.h) / dt;
2008  pos_geod(&sloc[2]);
2009 
2010  // Attitude at t0-2*dt
2011  sloc[2].att.lvlh = sloc[0].att.lvlh;
2012  att_lvlh2icrf(&sloc[2]);
2013 
2014  cinfo->node.phys.battlev = cinfo->node.phys.battcap;
2015 
2016  pos_accel(cinfo->node.phys, sloc[2]);
2017  simulate_hardware(cinfo, sloc[2]);
2018  att_accel(cinfo->node.phys, sloc[2]);
2019 
2020  // Position at t0-3*dt
2021  sloc[3].pos.geod.utc = sloc[3].att.geoc.utc = sloc[2].utc - dt/86400.;
2022  sloc[3].pos.geod.s.lat = sloc[2].pos.geod.s.lat - dt * sloc[2].pos.geod.v.lat;
2023  sloc[3].pos.geod.v.lat = sloc[2].pos.geod.v.lat;
2024  sloc[3].pos.geod.s.lon = sloc[2].pos.geod.s.lon - dt * sloc[2].pos.geod.v.lon;
2025  sloc[3].pos.geod.v.lon = (sloc[2].pos.geod.v.lon + DPI / 43200.) * cos(sloc[2].pos.geod.s.lat) / cos(sloc[3].pos.geod.s.lat) - DPI / 43200.;
2026  sloc[3].pos.geod.s.h = sloc[2].pos.geos.s.r - rearth(sloc[3].pos.geod.s.lat);
2027  sloc[3].pos.geod.v.h = (sloc[2].pos.geod.s.h - sloc[3].pos.geod.s.h) / dt;
2028  pos_geod(&sloc[3]);
2029 
2030  // Attitude at t0-3*dt
2031  sloc[3].att.lvlh = sloc[0].att.lvlh;
2032  att_lvlh2icrf(&sloc[3]);
2033 
2034  cinfo->node.phys.battlev = cinfo->node.phys.battcap;
2035 
2036  pos_accel(cinfo->node.phys, sloc[3]);
2037  simulate_hardware(cinfo, sloc[3]);
2038  att_accel(cinfo->node.phys, sloc[3]);
2039  cinfo->node.phys.utc = loc.utc;
2040 
2041  cinfo->timestamp = currentmjd();
2042 }
svector s
Position vector.
Definition: convertdef.h:318
qatt geoc
Definition: convertdef.h:828
double utc
Definition: convertdef.h:261
ElapsedTime dt
Definition: agent_file3.cpp:183
spherpos geos
Definition: convertdef.h:743
rvector a
2nd derivative: Alpha - acceleration
Definition: convertdef.h:483
void simulate_hardware(cosmosstruc *cinfo, vector< locstruc > &locvec)
Simulate Hardware data - multiple.
Definition: physicslib.cpp:937
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
const double DPI2
Double precision PI/2.
Definition: math/constants.h:18
qatt lvlh
Definition: convertdef.h:827
#define GM
SI Mass * Gravitational Constant for Earth.
Definition: convertdef.h:79
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
quaternion q_change_around_y(double angle)
Rotation quaternion for Y axis.
Definition: vector.cpp:1435
double utc
Definition: convertdef.h:477
static double initialutc
Definition: physicslib.cpp:43
int32_t pos_clear(locstruc *loc)
Initialize posstruc.
Definition: convertlib.cpp:77
quaternion q_drotate_between_rv(rvector from, rvector to)
Create rotation quaternion from 2 row vectors.
Definition: mathlib.cpp:81
attstruc att
attstruc for this time.
Definition: convertdef.h:883
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
qatt icrf
Definition: convertdef.h:830
double h
Height in meters.
Definition: vector.h:229
double lon
Longitude in radians.
Definition: vector.h:227
int32_t pos_geod(locstruc *loc)
Set Geodetic position.
Definition: convertlib.cpp:576
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
static locstruc sloc[MAXGJORDER+2]
Definition: physicslib.cpp:47
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
gvector s
Position vector.
Definition: convertdef.h:263
double lat
Latitude in radians.
Definition: vector.h:225
void hardware_init_eci(cosmosstruc *cinfo, locstruc &loc)
Initialize Hardware.
Definition: physicslib.cpp:877
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
geoidpos geod
Definition: convertdef.h:741
double r
Radius in meters.
Definition: vector.h:174
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:269
const double DPI
Double precision PI.
Definition: math/constants.h:14
gvector v
Velocity vector.
Definition: convertdef.h:265
Definition: convertdef.h:876
double rearth(double lat)
Definition: convertlib.cpp:1556
int32_t pos_accel(physicsstruc &physics, locstruc &loc)
Position acceleration.
Definition: physicslib.cpp:1553
void propagate ( cosmosstruc root,
double  mjd 
)
2045 {
2046  locstruc lnew, lnewp;
2047  rvector ds, unitp, unitx;
2048  quaternion dq;
2049  double angle;
2050  double lutc;
2051  uint32_t chunks, i, j;
2052 
2053  if (sloc[0].pos.geod.s.h < 100.)
2054  {
2055  return;
2056  }
2057 
2058  chunks = (uint32_t)(.5 + 86400.*(utc-sloc[0].utc)/cinfo->node.phys.dt);
2059  if (chunks > 100000)
2060  {
2061  chunks = 100000;
2062  }
2063  lutc = sloc[0].pos.geoc.utc;
2064  for (i=0; i<chunks; ++i)
2065  {
2066  if (sloc[0].pos.geod.s.h < 100.)
2067  {
2068  break;
2069  }
2070 
2071  lnew = lnewp = sloc[0];
2072 
2073  lutc += (double)(cinfo->node.phys.dt)/86400.;
2074 
2075  lnewp.utc = lnewp.att.icrf.utc = lutc;
2076 
2077  lnewp.pos.eci.s.col[0] += cinfo->node.phys.dt * (lnewp.pos.eci.v.col[0] + cinfo->node.phys.dt * (323.*sloc[0].pos.eci.a.col[0] - 264.*sloc[1].pos.eci.a.col[0] + 159.*sloc[2].pos.eci.a.col[0] - 38.*sloc[3].pos.eci.a.col[0]) / 360.);
2078  lnewp.pos.eci.s.col[1] += cinfo->node.phys.dt * (lnewp.pos.eci.v.col[1] + cinfo->node.phys.dt * (323.*sloc[0].pos.eci.a.col[1] - 264.*sloc[1].pos.eci.a.col[1] + 159.*sloc[2].pos.eci.a.col[1] - 38.*sloc[3].pos.eci.a.col[1]) / 360.);
2079  lnewp.pos.eci.s.col[2] += cinfo->node.phys.dt * (lnewp.pos.eci.v.col[2] + cinfo->node.phys.dt * (323.*sloc[0].pos.eci.a.col[2] - 264.*sloc[1].pos.eci.a.col[2] + 159.*sloc[2].pos.eci.a.col[2] - 38.*sloc[3].pos.eci.a.col[2]) / 360.);
2080  lnewp.pos.eci.v.col[0] += cinfo->node.phys.dt * (55.*sloc[0].pos.eci.a.col[0] - 59.*sloc[1].pos.eci.a.col[0] + 37.*sloc[2].pos.eci.a.col[0] - 9.*sloc[3].pos.eci.a.col[0]) / 24.;
2081  lnewp.pos.eci.v.col[1] += cinfo->node.phys.dt * (55.*sloc[0].pos.eci.a.col[1] - 59.*sloc[1].pos.eci.a.col[1] + 37.*sloc[2].pos.eci.a.col[1] - 9.*sloc[3].pos.eci.a.col[1]) / 24.;
2082  lnewp.pos.eci.v.col[2] += cinfo->node.phys.dt * (55.*sloc[0].pos.eci.a.col[2] - 59.*sloc[1].pos.eci.a.col[2] + 37.*sloc[2].pos.eci.a.col[2] - 9.*sloc[3].pos.eci.a.col[2]) / 24.;
2083  lnewp.pos.eci.pass++;
2084  pos_eci(&lnewp);
2085  pos_accel(cinfo->node.phys, lnewp);
2086 
2087  lnew.utc = lnew.att.icrf.utc = lutc;
2088  lnew.pos.eci.s.col[0] += cinfo->node.phys.dt * (lnew.pos.eci.v.col[0] + cinfo->node.phys.dt * (38.*lnewp.pos.eci.a.col[0] + 171.*sloc[0].pos.eci.a.col[0] - 36.*sloc[1].pos.eci.a.col[0] + 7.*sloc[2].pos.eci.a.col[0]) / 360.);
2089  lnew.pos.eci.s.col[1] += cinfo->node.phys.dt * (lnew.pos.eci.v.col[1] + cinfo->node.phys.dt * (38.*lnewp.pos.eci.a.col[1] + 171.*sloc[0].pos.eci.a.col[1] - 36.*sloc[1].pos.eci.a.col[1] + 7.*sloc[2].pos.eci.a.col[1]) / 360.);
2090  lnew.pos.eci.s.col[2] += cinfo->node.phys.dt * (lnew.pos.eci.v.col[2] + cinfo->node.phys.dt * (38.*lnewp.pos.eci.a.col[2] + 171.*sloc[0].pos.eci.a.col[2] - 36.*sloc[1].pos.eci.a.col[2] + 7.*sloc[2].pos.eci.a.col[2]) / 360.);
2091  lnew.pos.eci.v.col[0] += cinfo->node.phys.dt * (9.*lnewp.pos.eci.a.col[0] + 19.*sloc[0].pos.eci.a.col[0] - 5.*sloc[1].pos.eci.a.col[0] + sloc[2].pos.eci.a.col[0]) / 24.;
2092  lnew.pos.eci.v.col[1] += cinfo->node.phys.dt * (9.*lnewp.pos.eci.a.col[1] + 19.*sloc[0].pos.eci.a.col[1] - 5.*sloc[1].pos.eci.a.col[1] + sloc[2].pos.eci.a.col[1]) / 24.;
2093  lnew.pos.eci.v.col[2] += cinfo->node.phys.dt * (9.*lnewp.pos.eci.a.col[2] + 19.*sloc[0].pos.eci.a.col[2] - 5.*sloc[1].pos.eci.a.col[2] + sloc[2].pos.eci.a.col[2]) / 24.;
2094  lnew.pos.eci.pass++;
2095  pos_eci(&lnew);
2096  pos_accel(cinfo->node.phys, lnew);
2097 
2098 
2099  switch (cinfo->node.phys.mode)
2100  {
2101  case 0:
2102  lnew.att.icrf.utc = lnew.utc;
2103  ds = rv_zero();
2104  ds.col[0] = cinfo->node.phys.dt * (lnewp.att.icrf.v.col[0] + cinfo->node.phys.dt * (323.*sloc[0].att.icrf.a.col[0] - 264.*sloc[1].att.icrf.a.col[0] + 159.*sloc[2].att.icrf.a.col[0] - 38.*sloc[3].att.icrf.a.col[0]) / 360.);
2105  ds.col[1] = cinfo->node.phys.dt * (lnewp.att.icrf.v.col[1] + cinfo->node.phys.dt * (323.*sloc[0].att.icrf.a.col[1] - 264.*sloc[1].att.icrf.a.col[1] + 159.*sloc[2].att.icrf.a.col[1] - 38.*sloc[3].att.icrf.a.col[1]) / 360.);
2106  ds.col[2] = cinfo->node.phys.dt * (lnewp.att.icrf.v.col[2] + cinfo->node.phys.dt * (323.*sloc[0].att.icrf.a.col[2] - 264.*sloc[1].att.icrf.a.col[2] + 159.*sloc[2].att.icrf.a.col[2] - 38.*sloc[3].att.icrf.a.col[2]) / 360.);
2107  dq = q_axis2quaternion_rv(rv_smult(.1,ds));
2108  for (j=0; j<10; ++j)
2109  {
2110  lnewp.att.icrf.s = q_fmult(dq,lnewp.att.icrf.s);
2111  }
2112  lnewp.att.icrf.v.col[0] += cinfo->node.phys.dt * (55.*sloc[0].att.icrf.a.col[0] - 59.*sloc[1].att.icrf.a.col[0] + 37.*sloc[2].att.icrf.a.col[0] - 9.*sloc[3].att.icrf.a.col[0]) / 24.;
2113  lnewp.att.icrf.v.col[1] += cinfo->node.phys.dt * (55.*sloc[0].att.icrf.a.col[1] - 59.*sloc[1].att.icrf.a.col[1] + 37.*sloc[2].att.icrf.a.col[1] - 9.*sloc[3].att.icrf.a.col[1]) / 24.;
2114  lnewp.att.icrf.v.col[2] += cinfo->node.phys.dt * (55.*sloc[0].att.icrf.a.col[2] - 59.*sloc[1].att.icrf.a.col[2] + 37.*sloc[2].att.icrf.a.col[2] - 9.*sloc[3].att.icrf.a.col[2]) / 24.;
2115  att_icrf2lvlh(&lnew);
2116  att_accel(cinfo->node.phys, lnewp);
2117 
2118  ds = rv_zero();
2119  ds.col[0] = cinfo->node.phys.dt * (lnew.att.icrf.v.col[0] + cinfo->node.phys.dt * (38.*lnewp.att.icrf.a.col[0] + 171.*sloc[0].att.icrf.a.col[0] - 36.*sloc[1].att.icrf.a.col[0] + 7.*sloc[2].att.icrf.a.col[0]) / 3600.);
2120  ds.col[1] = cinfo->node.phys.dt * (lnew.att.icrf.v.col[1] + cinfo->node.phys.dt * (38.*lnewp.att.icrf.a.col[1] + 171.*sloc[0].att.icrf.a.col[1] - 36.*sloc[1].att.icrf.a.col[1] + 7.*sloc[2].att.icrf.a.col[1]) / 3600.);
2121  ds.col[2] = cinfo->node.phys.dt * (lnew.att.icrf.v.col[2] + cinfo->node.phys.dt * (38.*lnewp.att.icrf.a.col[2] + 171.*sloc[0].att.icrf.a.col[2] - 36.*sloc[1].att.icrf.a.col[2] + 7.*sloc[2].att.icrf.a.col[2]) / 3600.);
2122  dq = q_axis2quaternion_rv(rv_smult(.1,ds));
2123  for (j=0; j<10; ++j)
2124  {
2125  lnew.att.icrf.s = q_fmult(dq,lnew.att.icrf.s);
2126  }
2127  lnew.att.icrf.v.col[0] += cinfo->node.phys.dt * (9.*lnewp.att.icrf.a.col[0] + 19.*sloc[0].att.icrf.a.col[0] - 5.*sloc[1].att.icrf.a.col[0] + sloc[2].att.icrf.a.col[0]) / 24.;
2128  lnew.att.icrf.v.col[1] += cinfo->node.phys.dt * (9.*lnewp.att.icrf.a.col[1] + 19.*sloc[0].att.icrf.a.col[1] - 5.*sloc[1].att.icrf.a.col[1] + sloc[2].att.icrf.a.col[1]) / 24.;
2129  lnew.att.icrf.v.col[2] += cinfo->node.phys.dt * (9.*lnewp.att.icrf.a.col[2] + 19.*sloc[0].att.icrf.a.col[2] - 5.*sloc[1].att.icrf.a.col[2] + sloc[2].att.icrf.a.col[2]) / 24.;
2130  att_icrf2lvlh(&lnew);
2131  break;
2132  case 1:
2133  lnew.att.lvlh.utc = lnew.utc;
2134  lnew.att.lvlh.s = q_eye();
2135  lnew.att.lvlh.v = rv_zero();
2136  att_lvlh2icrf(&lnew);
2137  break;
2138  case 2:
2139  lnew.att.lvlh.utc = lnew.utc;
2140  lnew.att.lvlh.s = q_change_around_y(-DPI2);
2141  lnew.att.lvlh.v = rv_zero();
2142  att_lvlh2icrf(&lnew);
2143  break;
2144  case 3:
2145  lnew.att.icrf.utc = lnew.utc;
2146  lnew.att.icrf.s = q_drotate_between_rv(rv_unitz(),lnew.pos.eci.a);
2147  lnew.att.icrf.v = rv_zero();
2148  att_icrf2lvlh(&lnew);
2149  break;
2150  case 4:
2151  case 5:
2152  case 6:
2153  case 7:
2154  case 8:
2155  case 9:
2156  case 10:
2157  case 11:
2158  lnew.att.icrf.s = q_drotate_between_rv(cinfo->faces[abs(cinfo->pieces[cinfo->node.phys.mode-2].face_idx[0])].normal.to_rv(),rv_smult(-1.,lnew.pos.icrf.s));
2159  // lnew.att.icrf.s = rm_change_between_rv(cinfo->pieces[cinfo->node.phys.mode-2].normal,rv_smult(-1.,lnew.pos.icrf.s));
2160  lnew.att.icrf.v = rv_zero();
2161  att_icrf2lvlh(&lnew);
2162  break;
2163  case 12:
2164  angle = (1440.*(lnew.utc - initialutc) - (int)(1440.*(lnew.utc - initialutc))) * 2.*DPI;
2165  unitx = rv_zero();
2166  unitx.col[0] = 1.;
2167  unitp = rv_zero();
2168  unitp.col[0] = cos(angle);
2169  unitp.col[1] = sin(angle);
2170  lnew.att.lvlh.s = q_drotate_between_rv(unitp,unitx);
2171  lnew.att.lvlh.v = rv_zero();
2172  lnew.att.lvlh.v.col[2] = 2.*DPI/1440.;
2173  att_lvlh2icrf(&lnew);
2174  break;
2175  }
2176 
2177  // groundstations(cinfo,&lnew);
2178  cinfo->node.phys.battlev += (cinfo->node.phys.dt/3600.) * (cinfo->node.phys.powgen-cinfo->node.phys.powuse);
2179 
2180  if (cinfo->node.phys.powgen > cinfo->node.phys.powuse)
2181  cinfo->node.flags |= NODE_FLAG_CHARGING;
2182  else
2183  cinfo->node.flags &= ~NODE_FLAG_CHARGING;
2184 
2185  if (cinfo->node.phys.battlev < 0.)
2186  cinfo->node.phys.battlev = 0.;
2187 
2188  if (cinfo->node.phys.battlev > cinfo->node.phys.battcap)
2189  {
2190  cinfo->node.flags &= ~NODE_FLAG_CHARGING;
2191  cinfo->node.phys.battlev = cinfo->node.phys.battcap;
2192  }
2193  // Simulate hardware values
2194  simulate_hardware(cinfo, lnew);
2195  att_accel(cinfo->node.phys, lnew);
2196 
2197 
2198  sloc[3] = sloc[2];
2199  sloc[2] = sloc[1];
2200  sloc[1] = sloc[0];
2201  sloc[0] = lnew;
2202 
2203  }
2204 
2205  cinfo->node.loc = sloc[0];
2206 
2207  cinfo->timestamp = currentmjd();
2208 }
Definition: cosmos-defs.h:114
3 element generic row vector
Definition: vector.h:53
rvector a
Acceleration.
Definition: convertdef.h:167
double utc
UTC of Position.
Definition: convertdef.h:161
int i
Definition: rw_test.cpp:37
rvector a
2nd derivative: Alpha - acceleration
Definition: convertdef.h:483
void simulate_hardware(cosmosstruc *cinfo, vector< locstruc > &locvec)
Simulate Hardware data - multiple.
Definition: physicslib.cpp:937
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
Quaternion, scalar last, using x, y, z.
Definition: vector.h:402
cartpos geoc
Definition: convertdef.h:739
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
quaternion q_axis2quaternion_rv(rvector v)
Row vector axis and angle to Quaternion.
Definition: mathlib.cpp:260
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
const double DPI2
Double precision PI/2.
Definition: math/constants.h:18
qatt lvlh
Definition: convertdef.h:827
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
quaternion q_change_around_y(double angle)
Rotation quaternion for Y axis.
Definition: vector.cpp:1435
quaternion q_fmult(rvector r1, quaternion q2)
rvector quaternion multiply
Definition: vector.cpp:1079
double utc
Definition: convertdef.h:477
static double initialutc
Definition: physicslib.cpp:43
rvector s
Location.
Definition: convertdef.h:163
quaternion q_drotate_between_rv(rvector from, rvector to)
Create rotation quaternion from 2 row vectors.
Definition: mathlib.cpp:81
attstruc att
attstruc for this time.
Definition: convertdef.h:883
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
qatt icrf
Definition: convertdef.h:830
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
rvector rv_unitz(double scale)
Scaled z row vector.
Definition: vector.cpp:140
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
static locstruc sloc[MAXGJORDER+2]
Definition: physicslib.cpp:47
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
double col[3]
Definition: vector.h:55
cartpos eci
Definition: convertdef.h:737
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
const double DPI
Double precision PI.
Definition: math/constants.h:14
cartpos icrf
Definition: convertdef.h:736
Definition: convertdef.h:876
rvector v
Velocity.
Definition: convertdef.h:165
int32_t pos_accel(physicsstruc &physics, locstruc &loc)
Position acceleration.
Definition: physicslib.cpp:1553
double rearth ( double  lat)
1557 {
1558  double st,ct;
1559  double c;
1560 
1561  st = sin(lat);
1562  ct = cos(lat);
1563  c = sqrt(((FRATIO2 * FRATIO2 * st * st) + (ct * ct))/((ct * ct) + (FRATIO2 * st * st)));
1564  return (REARTHM * c);
1565 }
#define FRATIO2
Definition: convertdef.h:66
#define REARTHM
SI Radius of Earth.
Definition: convertdef.h:60
int update_eci ( cosmosstruc root,
double  utc,
cartpos  pos 
)
3298 {
3299  quaternion dsq, q1, q2;
3300  uvector utemp{};
3301  static rvector unitp1, unitp2, lunitp1;
3302  rvector unitp, unitx, normal, unitv;
3303  locstruc tloc;
3304  dem_pixel val;
3305  double angle;
3306  int j, k;
3307 
3308  cinfo->node.loc.utc = utc;
3309  cinfo->node.loc.pos.eci = pos;
3310  cinfo->node.loc.pos.eci.pass++;
3311  pos_eci(&cinfo->node.loc);
3312  if (cinfo->node.phys.mode == PHYSICS_MODE_SURFACE)
3313  {
3314  switch (cinfo->node.loc.pos.extra.closest)
3315  {
3316  case COSMOS_EARTH:
3317  default:
3318  cinfo->node.loc.pos.geod.s.h = 0.5;
3319  cinfo->node.loc.pos.geod.utc += 1e-8;
3320  pos_geod(&cinfo->node.loc);
3321  break;
3322  case COSMOS_MOON:
3323  cinfo->node.loc.pos.selg.s.h = 2.5;
3324  cinfo->node.loc.pos.selg.utc += 1e-8;
3325  pos_selg(&cinfo->node.loc);
3326  break;
3327  }
3328  }
3329  tloc = cinfo->node.loc;
3330  pos_accel(cinfo->node.phys, tloc);
3331 
3332  // Calculate probable thrust
3333  if (cinfo->devspec.thst_cnt)
3334  {
3335  cinfo->node.phys.thrust = rv_sub(cinfo->node.loc.pos.eci.a,tloc.pos.eci.a);
3336  if (length_rv(cinfo->node.phys.thrust.to_rv()) < 5.)
3337  {
3338  cinfo->node.phys.thrust = rv_zero();
3339  }
3340  else
3341  {
3342  cinfo->node.phys.thrust = rv_smult(cinfo->node.phys.mass,cinfo->node.phys.thrust.to_rv());
3343  }
3344  }
3345 
3346  // Calculate probable motor motion
3347  if (cinfo->devspec.motr_cnt)
3348  {
3349 
3350  for (j=0; j<cinfo->devspec.motr_cnt; j++)
3351  {
3352  switch (cinfo->node.loc.pos.extra.closest)
3353  {
3354  case COSMOS_EARTH:
3355  default:
3356  cinfo->device[cinfo->devspec.motr[j]].motr.spd = length_rv(cinfo->node.loc.pos.geoc.v)/cinfo->device[cinfo->devspec.motr[j]].motr.rat;
3357  break;
3358  case COSMOS_MOON:
3359  cinfo->device[cinfo->devspec.motr[j]].motr.spd = length_rv(cinfo->node.loc.pos.selc.v)/cinfo->device[cinfo->devspec.motr[j]].motr.rat;
3360  break;
3361  }
3362  }
3363  }
3364 
3365  switch (cinfo->node.phys.mode)
3366  {
3367  case 0:
3368  cinfo->node.loc.att.icrf.utc = cinfo->node.loc.utc;
3369  for (k=0; k<10; k++)
3370  {
3371  q1 = q_axis2quaternion_rv(rv_smult(cinfo->node.phys.dt/10.,cinfo->node.loc.att.icrf.v));
3372  cinfo->node.loc.att.icrf.s = q_fmult(q1,cinfo->node.loc.att.icrf.s);
3373  normalize_q(&cinfo->node.loc.att.icrf.s);
3374  cinfo->node.loc.att.icrf.v = rv_add(cinfo->node.loc.att.icrf.v,rv_smult(cinfo->node.phys.dt/10.,cinfo->node.loc.att.icrf.a));
3375  }
3376  att_icrf2lvlh(&cinfo->node.loc);
3377  break;
3378  case 1:
3379  cinfo->node.loc.att.lvlh.utc = cinfo->node.loc.utc;
3380  cinfo->node.loc.att.lvlh.s = q_eye();
3381  cinfo->node.loc.att.lvlh.v = rv_zero();
3382  att_lvlh2icrf(&cinfo->node.loc);
3383  break;
3384  case 2:
3385  cinfo->node.loc.att.topo.v = cinfo->node.loc.att.topo.a = rv_zero();
3386  switch (cinfo->node.loc.pos.extra.closest)
3387  {
3388  case COSMOS_EARTH:
3389  default:
3390  val = map_dem_pixel(COSMOS_EARTH,cinfo->node.loc.pos.geod.s.lon,cinfo->node.loc.pos.geod.s.lat,1./REARTHM);
3391  for (j=0; j<3; j++)
3392  {
3393  normal.col[j] = val.nmap[j];
3394  }
3395  unitv = rv_zero();
3396  unitv.col[0] = cinfo->node.loc.pos.geod.v.lon / cos(cinfo->node.loc.pos.geod.s.lat);
3397  unitv.col[1] = cinfo->node.loc.pos.geod.v.lat;
3398  break;
3399  case COSMOS_MOON:
3400  val = map_dem_pixel(COSMOS_MOON,cinfo->node.loc.pos.selg.s.lon,cinfo->node.loc.pos.selg.s.lat,1./RMOONM);
3401  for (j=0; j<3; j++)
3402  {
3403  normal.col[j] = -val.nmap[j];
3404  }
3405  unitv = rv_zero();
3406  unitv.col[0] = cinfo->node.loc.pos.selg.v.lon / cos(cinfo->node.loc.pos.selg.s.lat);
3407  unitv.col[1] = cinfo->node.loc.pos.selg.v.lat;
3408  break;
3409  }
3410  q1 = q_drotate_between_rv(rv_unitz(),normal);
3411  unitx = rv_cross(normal,rv_unity());
3412  unitx = irotate(q1,unitx);
3413  q2 = q_drotate_between_rv(unitx,unitv);
3414  // cinfo->node.loc.att.topo.s = q_fmult(q2,q1);
3415  cinfo->node.loc.att.topo.s = q1;
3416  cinfo->node.loc.att.topo.utc = cinfo->node.loc.pos.utc+1.e8;
3417  cinfo->node.loc.att.topo.pass++;
3418  att_topo(&cinfo->node.loc);
3419  break;
3420  case 3:
3421  cinfo->node.loc.att.icrf.utc = cinfo->node.loc.utc;
3422  q1 = cinfo->node.loc.att.icrf.s;
3423  cinfo->node.loc.att.icrf.s = q_drotate_between_rv(cinfo->node.phys.thrust.to_rv(),rv_unitz());
3424  dsq = q_sub(cinfo->node.loc.att.icrf.s,q1);
3425  angle = 2. * atan(length_q(dsq)/2.);
3426  q2 = q_smult(1./cos(angle),cinfo->node.loc.att.icrf.s);
3427  dsq = q_sub(q2,q1);
3428  utemp.q = q_smult(2.,q_fmult(q_conjugate(q1),dsq));
3429  cinfo->node.loc.att.icrf.v = utemp.r;
3430  att_icrf2lvlh(&cinfo->node.loc);
3431  break;
3432  case 4:
3433  cinfo->node.loc.att.selc.utc = cinfo->node.loc.utc;
3434  unitp1.col[0] += .1*(cinfo->node.loc.pos.selg.v.lon-unitp1.col[0]);
3435  unitp1.col[1] += .1*(cinfo->node.loc.pos.selg.v.lat-unitp1.col[1]);
3436  unitp1.col[2] = 0.;
3437  if (length_rv(unitp1) < 1e-9)
3438  unitp1 = lunitp1;
3439  else
3440  lunitp1 = unitp1;
3441  q1 = q_drotate_between_rv(rv_unitx(),unitp1);
3442  val = map_dem_pixel(COSMOS_MOON,cinfo->node.loc.pos.selg.s.lon,cinfo->node.loc.pos.selg.s.lat,.0003);
3443  unitp2.col[0] += .1*(val.nmap[0]-unitp2.col[0]);
3444  unitp2.col[1] += .1*(val.nmap[1]-unitp2.col[1]);
3445  unitp2.col[2] += .1*(val.nmap[2]-unitp2.col[2]);
3446  q2 = q_drotate_between_rv(irotate(q1,rv_unitz()),unitp2);
3447  cinfo->node.loc.att.selc.s = q_conjugate(q_fmult(q2,q1));
3448  cinfo->node.loc.att.selc.v = rv_zero();
3449  att_selc2icrf(&cinfo->node.loc);
3450  break;
3451  case 5:
3452  cinfo->node.loc.att.geoc.utc = cinfo->node.loc.utc;
3453  angle = 2.*acos(cinfo->node.loc.att.geoc.s.w);
3454  cinfo->node.loc.att.geoc.s = q_change_around_z(angle+.2*D2PI*cinfo->node.phys.dt);
3455  cinfo->node.loc.att.geoc.v = rv_smult(.2*D2PI,rv_unitz());
3456  att_geoc2icrf(&cinfo->node.loc);
3457  att_planec2lvlh(&cinfo->node.loc);
3458  break;
3459  case 6:
3460  case 7:
3461  case 8:
3462  case 9:
3463  case 10:
3464  case 11:
3465  cinfo->node.loc.att.icrf.s = q_drotate_between_rv(cinfo->faces[abs(cinfo->pieces[cinfo->node.phys.mode-2].face_idx[0])].normal.to_rv(),rv_smult(-1.,cinfo->node.loc.pos.icrf.s));
3466  cinfo->node.loc.att.icrf.v = rv_zero();
3467  att_icrf2lvlh(&cinfo->node.loc);
3468  break;
3469  case 12:
3470  angle = (1440.*(cinfo->node.loc.utc - initialutc) - (int)(1440.*(cinfo->node.loc.utc - initialutc))) * 2.*DPI;
3471  unitx = unitp = rv_zero();
3472  unitx.col[0] = 1.;
3473  unitp.col[0] = cos(angle);
3474  unitp.col[1] = sin(angle);
3475  cinfo->node.loc.att.lvlh.s = q_drotate_between_rv(unitp,unitx);
3476  cinfo->node.loc.att.lvlh.v = rv_zero();
3477  cinfo->node.loc.att.lvlh.v.col[2] = 2.*DPI/1440.;
3478  att_lvlh2icrf(&cinfo->node.loc);
3479  break;
3480  }
3481 
3482  // Perform positional and attitude accelerations at new position
3483  simulate_hardware(cinfo, cinfo->node.loc);
3484  att_accel(cinfo->node.phys, cinfo->node.loc);
3485 
3486  // Simulate at new position
3487  // groundstations(cinfo,&cinfo->node.loc);
3488 
3489  cinfo->timestamp = currentmjd();
3490  return 0;
3491 }
Quaternion/Rvector Union.
Definition: mathlib.h:155
float nmap[3]
Definition: demlib.h:85
Definition: eci2kep_test.cpp:33
quaternion q_sub(quaternion a, quaternion b)
Subtract two quaternions.
Definition: vector.cpp:1186
rvector rv_add(rvector a, rvector b)
Add two row vectors.
Definition: vector.cpp:299
3 element generic row vector
Definition: vector.h:53
rvector a
Acceleration.
Definition: convertdef.h:167
void simulate_hardware(cosmosstruc *cinfo, vector< locstruc > &locvec)
Simulate Hardware data - multiple.
Definition: physicslib.cpp:937
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
double length_rv(rvector v)
Length of row vector.
Definition: vector.cpp:748
Quaternion, scalar last, using x, y, z.
Definition: vector.h:402
quaternion q_conjugate(quaternion q)
Definition: vector.cpp:1010
#define PHYSICS_MODE_SURFACE
Definition: cosmos-defs.h:249
quaternion q_axis2quaternion_rv(rvector v)
Row vector axis and angle to Quaternion.
Definition: mathlib.cpp:260
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
int32_t pos_selg(locstruc *loc)
Set Selenographic position.
Definition: convertlib.cpp:484
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
quaternion q_fmult(rvector r1, quaternion q2)
rvector quaternion multiply
Definition: vector.cpp:1079
static double initialutc
Definition: physicslib.cpp:43
rvector rv_unity(double scale)
Scaled y row vector.
Definition: vector.cpp:129
quaternion q_smult(double a, quaternion b)
Multiply quaternion by scalar.
Definition: vector.cpp:1151
double length_q(quaternion q)
Length of quaternion.
Definition: vector.cpp:1329
quaternion q_drotate_between_rv(rvector from, rvector to)
Create rotation quaternion from 2 row vectors.
Definition: mathlib.cpp:81
void normalize_q(quaternion *q)
Definition: vector.cpp:961
dem_pixel map_dem_pixel(int body, double lon, double lat, double res)
Height in DEM.
Definition: demlib.cpp:342
int32_t att_planec2lvlh(locstruc *loc)
Convert ITRS attitude to LVLH attitude.
Definition: convertlib.cpp:1863
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
quaternion q_change_around_z(double angle)
Rotation quaternion for Z axis.
Definition: vector.cpp:1461
int32_t att_geoc2icrf(locstruc *loc)
Definition: convertlib.cpp:1639
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
#define RMOONM
SI Radius of Moon.
Definition: convertdef.h:58
rvector rv_unitz(double scale)
Scaled z row vector.
Definition: vector.cpp:140
int32_t pos_geod(locstruc *loc)
Set Geodetic position.
Definition: convertlib.cpp:576
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
int32_t att_selc2icrf(locstruc *loc)
Definition: convertlib.cpp:1760
#define COSMOS_MOON
Definition: convertdef.h:144
#define COSMOS_EARTH
Definition: convertdef.h:137
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
#define REARTHM
SI Radius of Earth.
Definition: convertdef.h:60
const double D2PI
Double precision 2*PI.
Definition: math/constants.h:16
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
double col[3]
Definition: vector.h:55
rvector irotate(quaternion q, rvector v)
Indirectly rotate a row vector using a quaternion.
Definition: mathlib.cpp:2308
cartpos eci
Definition: convertdef.h:737
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
const double DPI
Double precision PI.
Definition: math/constants.h:14
Location value.
Definition: demlib.h:82
rvector rv_unitx(double scale)
Scaled x row vector.
Definition: vector.cpp:118
rvector rv_sub(rvector a, rvector b)
Subtract two vectors.
Definition: vector.cpp:315
int32_t att_topo(locstruc *loc)
Definition: convertlib.cpp:2252
rvector rv_cross(rvector a, rvector b)
Take cross product of two row vectors.
Definition: vector.cpp:363
Definition: convertdef.h:876
int32_t pos_accel(physicsstruc &physics, locstruc &loc)
Position acceleration.
Definition: physicslib.cpp:1553
void hardware_init_eci ( cosmosstruc cinfo,
locstruc loc 
)

Initialize Hardware.

Set up the hardware simulation by initializing the various components to their base values.

Parameters
devspecPointer to structure holding specs on devices.
locStructure specifying location

Initialize temperature sensors

Reaction Wheels

Magnetic Torque Rods

Star Trackers

878 {
879  uint16_t i;
880 
881  // Initialize power
882  // cinfo->node.phys.battlev = cinfo->node.phys.battcap;
883  for (i=0; i<cinfo->devspec.bus_cnt; i++)
884  {
885  cinfo->device[cinfo->devspec.bus[i]].amp = 0.;
886  cinfo->device[cinfo->devspec.bus[i]].flag |= DEVICE_FLAG_ON;
887  }
888 
890 // for (i=0; i<cinfo->devspec.tsen_cnt; i++)
891 // {
892 // cinfo->device[cinfo->devspec.tsen[i]].temp = 300.;
893 // }
894 
896  for (i=0; i<cinfo->devspec.rw_cnt; i++)
897  {
898  cinfo->device[cinfo->devspec.rw[i]].utc = loc.utc;
899  cinfo->device[cinfo->devspec.rw[i]].rw.omg = cinfo->device[cinfo->devspec.rw[i]].rw.alp = 0.;
900  cinfo->device[cinfo->devspec.rw[i]].rw.romg = cinfo->device[cinfo->devspec.rw[i]].rw.ralp = 0.;
901  }
902 
904  if (cinfo->devspec.tcu_cnt)
905  {
906  cinfo->device[cinfo->devspec.tcu[0]].utc = loc.utc;
907  for (i=0; i<cinfo->devspec.mtr_cnt; i++)
908  {
909  cinfo->device[cinfo->devspec.mtr[i]].utc = loc.utc;
910  cinfo->device[cinfo->devspec.mtr[i]].mtr.mom = 0.;
911  cinfo->device[cinfo->devspec.mtr[i]].mtr.rmom = 0.;
912  }
913  }
914 
915  // Inertial Measurement Units
916  for (i=0; i<cinfo->devspec.imu_cnt; i++)
917  {
918  initialize_imu(i, cinfo->devspec, loc);
919  cinfo->device[cinfo->devspec.imu[i]].utc = loc.utc;
920  }
921 
923  for (i=0; i<cinfo->devspec.stt_cnt; i++)
924  {
925  cinfo->device[cinfo->devspec.stt[i]].stt.att = q_fmult(cinfo->device[cinfo->devspec.stt[i]].stt.align,q_conjugate(loc.att.icrf.s));
926  cinfo->device[cinfo->devspec.stt[i]].stt.omega = irotate(q_conjugate(cinfo->device[cinfo->devspec.stt[i]].stt.align),loc.att.icrf.v);
927  cinfo->device[cinfo->devspec.stt[i]].utc = loc.utc;
928  }
929 }
uint16_t imu_cnt
Definition: jsondef.h:3871
vector< uint16_t > mtr
Definition: jsondef.h:3907
vector< uint16_t > stt
Definition: jsondef.h:3916
vector< uint16_t > bus
Definition: jsondef.h:3898
int i
Definition: rw_test.cpp:37
quaternion q_conjugate(quaternion q)
Definition: vector.cpp:1010
void initialize_imu(uint16_t index, devspecstruc &devspec, locstruc &loc)
Initialize IMU.
Definition: physicslib.cpp:1452
vector< uint16_t > imu
Definition: jsondef.h:3904
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
vector< uint16_t > rw
Definition: jsondef.h:3913
#define DEVICE_FLAG_ON
Definition: jsondef.h:634
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
vector< uint16_t > tcu
Definition: jsondef.h:3919
quaternion q_fmult(rvector r1, quaternion q2)
rvector quaternion multiply
Definition: vector.cpp:1079
vector< devicestruc > device
Vector of all general (common) information for devices (components) in node.
Definition: jsondef.h:4238
attstruc att
attstruc for this time.
Definition: convertdef.h:883
uint16_t bus_cnt
Definition: jsondef.h:3865
qatt icrf
Definition: convertdef.h:830
uint16_t rw_cnt
Definition: jsondef.h:3880
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
rvector irotate(quaternion q, rvector v)
Indirectly rotate a row vector using a quaternion.
Definition: mathlib.cpp:2308
devspecstruc devspec
Structure for devices (components) special data in node, by type.
Definition: jsondef.h:4241
uint16_t tcu_cnt
Definition: jsondef.h:3887
uint16_t mtr_cnt
Definition: jsondef.h:3874
uint16_t stt_cnt
Definition: jsondef.h:3884
void gauss_jackson_setup ( gj_handle gjh,
uint32_t  order,
double  utc,
double &  dt 
)

Prepare for Gauss-Jackson integration.

Initializes Gauss-Jackson integration parameters for indicated order (must be even). Binomial coefficients are initialized first time through.

Parameters
gjhgj_handle containing Gauss-Jackson inforation.
orderThe order at which the integration will be performed
utcInitial Modified Julian Day.
dtStep size in seconds.
2220 {
2221  uint32_t i, n, j,m,k;
2222  double test;
2223 
2224  gjh.step.resize(order+2);
2225  gjh.binom.resize(order+2);
2226  gjh.beta.resize(order+2);
2227  gjh.alpha.resize(order+2);
2228  for (i=0; i<order+2; ++i)
2229  {
2230  gjh.binom[i].resize(order+2);
2231  gjh.beta[i].resize(order+1);
2232  gjh.alpha[i].resize(order+1);
2233  }
2234  gjh.c.resize(order+3);
2235  gjh.gam.resize(order+2);
2236  gjh.q.resize(order+3);
2237  gjh.lam.resize(order+3);
2238  gjh.order = 0;
2239 
2240  // Munge time step to fit local granularity
2241  test = utc + dt/86400.;
2242  dt = 86400.*(test-utc);
2243 
2244  gjh.order = order;
2245  gjh.order2 = gjh.order/2;
2246  gjh.order = gjh.order2 * 2;
2247  gjh.dt = dt;
2248  gjh.dtsq = gjh.dt * gjh.dt;
2249 
2250  for (m=0; m<gjh.order+2; m++)
2251  {
2252  for (i=0; i<gjh.order+2; i++)
2253  {
2254  if (m > i)
2255  gjh.binom[m][i] = 0;
2256  else
2257  {
2258  if (m == i)
2259  gjh.binom[m][i] = 1;
2260  else
2261  {
2262  if (m == 0)
2263  gjh.binom[m][i] = 1;
2264  else
2265  {
2266  gjh.binom[m][i] = gjh.binom[m-1][i-1] + gjh.binom[m][i-1];
2267  }
2268  }
2269  }
2270  }
2271  }
2272 
2273  gjh.c[0] = 1.;
2274  for (n=1; n<gjh.order+3; n++)
2275  {
2276  gjh.c[n] = 0.;
2277  for (i=0; i<=n-1; i++)
2278  {
2279  gjh.c[n] -= gjh.c[i] / (n+1-i);
2280  }
2281  }
2282 
2283  gjh.gam[0] = gjh.c[0];
2284  for (i=1; i<gjh.order+2; i++)
2285  {
2286  gjh.gam[i] = gjh.gam[i-1] + gjh.c[i];
2287  }
2288 
2289  for (i=0; i<gjh.order+1; i++)
2290  {
2291  gjh.beta[gjh.order+1][i] = gjh.gam[i+1];
2292  gjh.beta[gjh.order][i] = gjh.c[i+1];
2293  for (j=gjh.order-1; j<gjh.order; --j)
2294  {
2295  if (!i)
2296  gjh.beta[j][i] = gjh.beta[j+1][i];
2297  else
2298  gjh.beta[j][i] = gjh.beta[j+1][i] - gjh.beta[j+1][i-1];
2299  }
2300  }
2301 
2302  gjh.q[0] = 1.;
2303  for (i=1; i<gjh.order+3; i++)
2304  {
2305  gjh.q[i] = 0.;
2306  for (k=0; k<=i; k++)
2307  {
2308  gjh.q[i] += gjh.c[k]*gjh.c[i-k];
2309  }
2310  }
2311 
2312  gjh.lam[0] = gjh.q[0];
2313  for (i=1; i<gjh.order+3; i++)
2314  {
2315  gjh.lam[i] = gjh.lam[i-1] + gjh.q[i];
2316  }
2317 
2318  for (i=0; i<gjh.order+1; i++)
2319  {
2320  gjh.alpha[gjh.order+1][i] = gjh.lam[i+2];
2321  gjh.alpha[gjh.order][i] = gjh.q[i+2];
2322  for (j=gjh.order-1; j<gjh.order; --j)
2323  {
2324  if (!i)
2325  gjh.alpha[j][i] = gjh.alpha[j+1][i];
2326  else
2327  gjh.alpha[j][i] = gjh.alpha[j+1][i] - gjh.alpha[j+1][i-1];
2328  }
2329  }
2330 
2331  for (j=0; j<gjh.order+2; j++)
2332  {
2333  for (m=0; m<gjh.order+1; m++)
2334  {
2335  gjh.step[j].a[gjh.order-m] = gjh.step[j].b[gjh.order-m] = 0.;
2336  for (i=m; i<=gjh.order; i++)
2337  {
2338  gjh.step[j].a[gjh.order-m] += gjh.alpha[j][i] * gjh.binom[m][i];
2339  gjh.step[j].b[gjh.order-m] += gjh.beta[j][i] * gjh.binom[m][i];
2340  }
2341  gjh.step[j].a[gjh.order-m] *= pow(-1.,m);
2342  gjh.step[j].b[gjh.order-m] *= pow(-1.,m);
2343  if (gjh.order-m == j)
2344  gjh.step[j].b[gjh.order-m] += .5;
2345  }
2346  }
2347 }
ElapsedTime dt
Definition: agent_file3.cpp:183
int i
Definition: rw_test.cpp:37
vector< vector< int32_t > > binom
Definition: physicsdef.h:100
double dt
Definition: physicsdef.h:107
vector< vector< double > > alpha
Definition: physicsdef.h:106
vector< double > q
Definition: physicsdef.h:104
vector< double > c
Definition: physicsdef.h:101
void test()
Definition: testprofiler.c:34
vector< vector< double > > beta
Definition: physicsdef.h:103
uint32_t order
Definition: physicsdef.h:109
uint32_t order2
Definition: physicsdef.h:110
double dtsq
Definition: physicsdef.h:108
vector< gjstruc > step
Definition: physicsdef.h:111
vector< double > lam
Definition: physicsdef.h:105
vector< double > gam
Definition: physicsdef.h:102
void gauss_jackson_init_tle ( gj_handle gjh,
uint32_t  order,
int32_t  mode,
double  dt,
double  mjd,
cosmosstruc cinfo 
)
void gauss_jackson_init_eci ( gj_handle gjh,
uint32_t  order,
int32_t  mode,
double  dt,
double  utc,
cartpos  ipos,
qatt  iatt,
physicsstruc physics,
locstruc loc 
)

Initialize Gauss-Jackson orbit using ECI state vector.

Initializes Gauss-Jackson structures using supplied initial state vector.

Parameters
gjhReference to gj_handle for Gauss-Jackson integration.
orderthe order at which the integration will be performed (must be even)
modeMode of physics propagation. Zero is free propagation.
dtStep size in seconds
utcInitial step time as UTC in Modified Julian Days
iposInitial ECI Position
iattInitial ICRF Attitude
physicsReference to physicsstruc to use.
locReference to locstruc to use.
2480 {
2481  kepstruc kep;
2482  double dea;
2483  uint32_t i;
2484  quaternion q1;
2485 
2486  // dt is modified during setup
2487  gauss_jackson_setup(gjh, order, utc, dt);
2488  physics.dt = dt;
2489  physics.dtj = physics.dt/86400.;
2490  physics.mode = mode;
2491 
2492  pos_clear(loc);
2493  gjh.step[gjh.order+1].sloc = loc;
2494  ipos.pass = iatt.pass = 0;
2495  loc.pos.eci = ipos;
2496  loc.pos.eci.pass++;
2497  loc.utc = loc.pos.eci.utc= utc;
2498  pos_eci(&loc);
2499 
2500  // Initial attitude
2501  switch (physics.mode)
2502  {
2503  case 0:
2504  // Pure propagation
2505  loc.att.icrf = iatt;
2506  loc.att.icrf.pass++;
2507  att_icrf(&loc);
2508  break;
2509  case 1:
2510  // Force LVLH
2511  loc.att.lvlh.utc = loc.utc;
2512  loc.att.lvlh.s = q_eye();
2513  loc.att.lvlh.v = rv_zero();
2514  loc.att.lvlh.pass++;
2515  att_lvlh(&loc);
2516  break;
2517  case 2:
2518  // Force 90 degrees off LVLH
2519  loc.att.lvlh.utc = loc.utc;
2520  loc.att.lvlh.s = q_change_around_y(-DPI2);
2521  loc.att.lvlh.v = rv_zero();
2522  pos_eci2geoc(&loc);
2523  att_lvlh2icrf(&loc);
2524  break;
2525  case 3:
2526  case 4:
2527  case 5:
2528  case 6:
2529  case 7:
2530  case 8:
2531  case 9:
2532  case 10:
2533  case 11:
2534  case 12:
2535  // loc.att.icrf.s = q_drotate_between_rv(cinfo->pieces[physics.mode-2].normal,rv_smult(-1.,loc.pos.icrf.s));
2536  loc.att.icrf.v = rv_zero();
2537  pos_eci2geoc(&loc);
2538  att_icrf2lvlh(&loc);
2539  break;
2540  }
2541 
2542  // simulate_hardware(cinfo, loc);
2543  pos_accel(physics, loc);
2544  // simulate_hardware(cinfo, loc);
2545  att_accel(physics, loc);
2546 
2547  gjh.step[gjh.order2].sloc = loc;
2548 
2549  // Position at t0-dt
2550  eci2kep(loc.pos.eci,kep);
2551  // kep2eci(&kep,&gjh.step[gjh.order2].sloc.pos.eci);
2552  for (i=gjh.order2-1; i<gjh.order2; --i)
2553  {
2554  gjh.step[i].sloc = gjh.step[i+1].sloc;
2555  gjh.step[i].sloc.utc -= dt / 86400.;
2556  kep.utc = gjh.step[i].sloc.att.icrf.utc = gjh.step[i].sloc.utc;
2557  kep.ma -= dt * kep.mm;
2558 
2559  uint16_t count = 0;
2560  do
2561  {
2562  dea = (kep.ea - kep.e * sin(kep.ea) - kep.ma) / (1. - kep.e * cos(kep.ea));
2563  kep.ea -= dea;
2564  } while (++count < 100 && fabs(dea) > .000001);
2565  kep2eci(kep,gjh.step[i].sloc.pos.eci);
2566  gjh.step[i].sloc.pos.eci.pass++;
2567 
2568  q1 = q_axis2quaternion_rv(rv_smult(-dt,gjh.step[i].sloc.att.icrf.v));
2569  gjh.step[i].sloc.att.icrf.s = q_fmult(q1,gjh.step[i].sloc.att.icrf.s);
2570  normalize_q(&gjh.step[i].sloc.att.icrf.s);
2571  // Calculate new v from da
2572  gjh.step[i].sloc.att.icrf.v = rv_add(gjh.step[i].sloc.att.icrf.v,rv_smult(-dt,gjh.step[i].sloc.att.icrf.a));
2573  // gjh.step[i].sloc.att.icrf.utc -= dt/86400.;
2574  // att_icrf2lvlh(&gjh.step[i].sloc);
2575  pos_eci(&gjh.step[i].sloc);
2576 
2577  pos_accel(physics, gjh.step[i].sloc);
2578  // Initialize hardware
2579  // hardware_init_eci(cinfo,gjh.step[i].sloc);
2580  att_accel(physics, gjh.step[i].sloc);
2581  }
2582 
2583  eci2kep(loc.pos.eci,kep);
2584  for (i=gjh.order2+1; i<=gjh.order; i++)
2585  {
2586  gjh.step[i].sloc = gjh.step[i-1].sloc;
2587  gjh.step[i].sloc.utc += dt / 86400.;
2588  kep.utc = gjh.step[i].sloc.att.icrf.utc = gjh.step[i].sloc.utc;
2589  kep.ma += dt * kep.mm;
2590 
2591  uint16_t count = 0;
2592  do
2593  {
2594  dea = (kep.ea - kep.e * sin(kep.ea) - kep.ma) / (1. - kep.e * cos(kep.ea));
2595  kep.ea -= dea;
2596  } while (++count < 100 && fabs(dea) > .000001);
2597  kep2eci(kep,gjh.step[i].sloc.pos.eci);
2598  gjh.step[i].sloc.pos.eci.pass++;
2599 
2600  q1 = q_axis2quaternion_rv(rv_smult(dt,gjh.step[i].sloc.att.icrf.v));
2601  gjh.step[i].sloc.att.icrf.s = q_fmult(q1,gjh.step[i].sloc.att.icrf.s);
2602  normalize_q(&gjh.step[i].sloc.att.icrf.s);
2603  // Calculate new v from da
2604  gjh.step[i].sloc.att.icrf.v = rv_add(gjh.step[i].sloc.att.icrf.v,rv_smult(dt,gjh.step[i].sloc.att.icrf.a));
2605  // gjh.step[i].sloc.att.icrf.utc += dt/86400.;
2606  // att_icrf2lvlh(&gjh.step[i].sloc);
2607  pos_eci(&gjh.step[i].sloc);
2608 
2609  pos_accel(physics, gjh.step[i].sloc);
2610  // Initialize hardware
2611  // hardware_init_eci(cinfo, gjh.step[i].sloc);
2612  att_accel(physics, gjh.step[i].sloc);
2613  }
2614  loc = gauss_jackson_converge_orbit(gjh, physics);
2615  gauss_jackson_converge_hardware(gjh, physics);
2616  physics.utc = loc.utc;
2617 }
int32_t eci2kep(cartpos &eci, kepstruc &kep)
Definition: convertlib.cpp:2934
double mm
Mean Motion.
Definition: convertdef.h:561
rvector rv_add(rvector a, rvector b)
Add two row vectors.
Definition: vector.cpp:299
ElapsedTime dt
Definition: agent_file3.cpp:183
double utc
UTC time of state vector in MJD.
Definition: convertdef.h:532
double utc
UTC of Position.
Definition: convertdef.h:161
int i
Definition: rw_test.cpp:37
double e
Eccentricity.
Definition: convertdef.h:540
int count
Definition: rw_test.cpp:36
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
double ma
Mean Anomoly.
Definition: convertdef.h:555
Quaternion, scalar last, using x, y, z.
Definition: vector.h:402
int32_t kep2eci(kepstruc &kep, cartpos &eci)
Definition: convertlib.cpp:2878
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
int32_t att_icrf(locstruc *loc)
Definition: convertlib.cpp:1836
quaternion q_axis2quaternion_rv(rvector v)
Row vector axis and angle to Quaternion.
Definition: mathlib.cpp:260
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
const double DPI2
Double precision PI/2.
Definition: math/constants.h:18
qatt lvlh
Definition: convertdef.h:827
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
quaternion q_change_around_y(double angle)
Rotation quaternion for Y axis.
Definition: vector.cpp:1435
quaternion q_fmult(rvector r1, quaternion q2)
rvector quaternion multiply
Definition: vector.cpp:1079
double utc
Definition: convertdef.h:477
int32_t pos_clear(locstruc *loc)
Initialize posstruc.
Definition: convertlib.cpp:77
void normalize_q(quaternion *q)
Definition: vector.cpp:961
attstruc att
attstruc for this time.
Definition: convertdef.h:883
locstruc gauss_jackson_converge_orbit(gj_handle &gjh, physicsstruc &physics)
Definition: physicslib.cpp:2761
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
int32_t pos_eci2geoc(locstruc *loc)
Convert ECI to GEOC.
Definition: convertlib.cpp:836
qatt icrf
Definition: convertdef.h:830
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
Classical elements structure.
Definition: convertdef.h:529
uint32_t order
Definition: physicsdef.h:109
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
uint32_t order2
Definition: physicsdef.h:110
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:485
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
double dt
Time step in seconds.
Definition: jsondef.h:3414
void gauss_jackson_converge_hardware(gj_handle &gjh, physicsstruc &physics)
Definition: physicslib.cpp:2862
cartpos eci
Definition: convertdef.h:737
vector< gjstruc > step
Definition: physicsdef.h:111
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
int32_t mode
Definition: jsondef.h:3436
double ea
Eccentric Anomoly.
Definition: convertdef.h:559
double utc
Simulated starting time in MJD.
Definition: jsondef.h:3418
double dtj
Time step in Julian days.
Definition: jsondef.h:3416
int32_t att_lvlh(locstruc *loc)
Definition: convertlib.cpp:2064
void gauss_jackson_setup(gj_handle &gjh, uint32_t order, double utc, double &dt)
Prepare for Gauss-Jackson integration.
Definition: physicslib.cpp:2219
int32_t pos_accel(physicsstruc &physics, locstruc &loc)
Position acceleration.
Definition: physicslib.cpp:1553
void gauss_jackson_init_stk ( gj_handle gjh,
uint32_t  order,
int32_t  mode,
double  dt,
double  mjd,
stkstruc stk,
physicsstruc physics,
locstruc loc 
)
2620 {
2621  uint32_t i;
2622 
2623  physics.dt = dt;
2624  physics.mode = mode;
2625  gauss_jackson_setup(gjh, order, utc, physics.dt);
2626  physics.dtj = physics.dt/86400.;
2627 
2628  pos_clear(loc);
2629  gjh.step[gjh.order+1].sloc = loc;
2630  stk2eci(utc,stk,loc.pos.eci);
2631  loc.att.icrf.utc = utc;
2632  loc.pos.eci.pass++;
2633  pos_eci(&loc);
2634 
2635  // Initial attitude
2636  physics.ftorque = rv_zero();
2637  switch (physics.mode)
2638  {
2639  //case 0:
2640  // loc.att.icrf.utc = loc.utc;
2641  // loc.att.icrf.s = q_eye();
2642  // loc.att.icrf.v = loc.att.icrf.a = rv_zero();
2643  // att_icrf(&loc);
2644  // break;
2645  case 1:
2646  loc.att.lvlh.utc = loc.utc;
2647  loc.att.lvlh.s = q_eye();
2648  loc.att.lvlh.v = rv_zero();
2649  att_lvlh2icrf(&loc);
2650  break;
2651  case 2:
2652  loc.att.lvlh.utc = loc.utc;
2653  loc.att.lvlh.s = q_change_around_y(-DPI2);
2654  loc.att.lvlh.v = rv_zero();
2655  att_lvlh2icrf(&loc);
2656  break;
2657  case 3:
2658  case 4:
2659  case 5:
2660  case 6:
2661  case 7:
2662  case 8:
2663  case 9:
2664  case 10:
2665  case 11:
2666  case 12:
2667  // loc.att.icrf.s = q_drotate_between_rv(physics.pieces[physics.mode-2].normal,rv_smult(-1.,loc.pos.icrf.s));
2668  loc.att.icrf.v = rv_zero();
2669  att_icrf2lvlh(&loc);
2670  break;
2671  }
2672 
2673 
2674  // Initialize hardware
2675  // hardware_init_eci(physics.devspec, loc);
2676  att_accel(physics, loc);
2677  // groundstations(cinfo,&loc);
2678 
2679  gjh.step[gjh.order2].sloc = loc;
2680 
2681  // Position at t0-dt
2682  for (i=gjh.order2-1; i<gjh.order2; --i)
2683  {
2684  gjh.step[i].sloc = gjh.step[i+1].sloc;
2685  gjh.step[i].sloc.utc -= dt / 86400.;
2686  gjh.step[i].sloc.att.icrf.utc = gjh.step[i].sloc.utc;
2687  stk2eci(gjh.step[i].sloc.utc,stk,gjh.step[i].sloc.pos.eci);
2688  gjh.step[i].sloc.pos.eci.pass++;
2689  pos_eci(&gjh.step[i].sloc);
2690 
2691  gjh.step[i].sloc.att.lvlh = gjh.step[i+1].sloc.att.lvlh;
2692  att_lvlh2icrf(&gjh.step[i].sloc);
2693 
2694  // Initialize hardware
2695  // hardware_init_eci(physics.devspec,gjh.step[i].sloc);
2696  att_accel(physics, gjh.step[i].sloc);
2697  }
2698 
2699  for (i=gjh.order2+1; i<=gjh.order; i++)
2700  {
2701  gjh.step[i].sloc = gjh.step[i-1].sloc;
2702  gjh.step[i].sloc.utc += dt / 86400.;
2703  stk2eci(gjh.step[i].sloc.utc,stk,gjh.step[i].sloc.pos.eci);
2704  gjh.step[i].sloc.pos.eci.pass++;
2705  pos_eci(&gjh.step[i].sloc);
2706 
2707  gjh.step[i].sloc.att.lvlh = gjh.step[i-1].sloc.att.lvlh;
2708  gjh.step[i].sloc.att.lvlh.utc = gjh.step[i].sloc.utc;
2709  att_lvlh2icrf(&gjh.step[i].sloc);
2710 
2711  // Initialize hardware
2712  // hardware_init_eci(physics.devspec,gjh.step[i].sloc);
2713  att_accel(physics, gjh.step[i].sloc);
2714  }
2715 
2716  loc = gauss_jackson_converge_orbit(gjh, physics);
2717  gauss_jackson_converge_hardware(gjh, physics);
2718  physics.utc = loc.utc;
2719 }
ElapsedTime dt
Definition: agent_file3.cpp:183
int i
Definition: rw_test.cpp:37
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
Vector ftorque
Definition: jsondef.h:3437
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
const double DPI2
Double precision PI/2.
Definition: math/constants.h:18
qatt lvlh
Definition: convertdef.h:827
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
quaternion q_change_around_y(double angle)
Rotation quaternion for Y axis.
Definition: vector.cpp:1435
double utc
Definition: convertdef.h:477
int32_t pos_clear(locstruc *loc)
Initialize posstruc.
Definition: convertlib.cpp:77
attstruc att
attstruc for this time.
Definition: convertdef.h:883
locstruc gauss_jackson_converge_orbit(gj_handle &gjh, physicsstruc &physics)
Definition: physicslib.cpp:2761
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
qatt icrf
Definition: convertdef.h:830
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
uint32_t order
Definition: physicsdef.h:109
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
uint32_t order2
Definition: physicsdef.h:110
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
double dt
Time step in seconds.
Definition: jsondef.h:3414
void gauss_jackson_converge_hardware(gj_handle &gjh, physicsstruc &physics)
Definition: physicslib.cpp:2862
cartpos eci
Definition: convertdef.h:737
vector< gjstruc > step
Definition: physicsdef.h:111
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
int32_t mode
Definition: jsondef.h:3436
double utc
Simulated starting time in MJD.
Definition: jsondef.h:3418
double dtj
Time step in Julian days.
Definition: jsondef.h:3416
void gauss_jackson_setup(gj_handle &gjh, uint32_t order, double utc, double &dt)
Prepare for Gauss-Jackson integration.
Definition: physicslib.cpp:2219
int stk2eci(double utc, stkstruc &stk, cartpos &eci)
ECI from STK data.
Definition: convertlib.cpp:3842
void gauss_jackson_init ( gj_handle gjh,
uint32_t  order,
int32_t  mode,
double  dt,
double  mjd,
double  altitude,
double  angle,
double  hour,
locstruc iloc,
physicsstruc physics,
locstruc loc 
)
2722 {
2723  double lon;
2724  kepstruc kep;
2725 
2726  lon = D2PI * (fabs(hour)/24. - (utc - (int)utc));
2727  if (lon < -DPI)
2728  lon += D2PI;
2729  if (lon > DPI)
2730  lon -= D2PI;
2731 
2732  physics.dt = dt;
2733  physics.mode = mode;
2734  gauss_jackson_setup(gjh, order, utc, physics.dt);
2735  physics.dtj = physics.dt/86400.;
2736  initialutc = utc;
2737 
2738  // Initial position
2739  pos_clear(iloc);
2740  kep.utc = utc;
2741  kep.a = REARTHM + altitude;
2742  kep.i = angle;
2743  kep.e = 0.;
2744  kep.ea = 0.;
2745  kep.ap = 0.;
2746  kep.raan = lon;
2747  kep2eci(kep, iloc.pos.geoc);
2748  ++iloc.pos.geoc.pass;
2749  pos_geoc(&iloc);
2750 
2751  iloc.att.lvlh.s = q_eye();
2752  iloc.att.lvlh.v = rv_zero();
2753  iloc.att.lvlh.a = rv_zero();
2754  ++iloc.att.lvlh.pass;
2755  att_lvlh(&iloc);
2756 
2757  gauss_jackson_init_eci(gjh, order, mode, physics.dt, utc, iloc.pos.eci, iloc.att.icrf, physics, loc);
2758  physics.utc = iloc.utc;
2759 }
ElapsedTime dt
Definition: agent_file3.cpp:183
double utc
UTC time of state vector in MJD.
Definition: convertdef.h:532
double e
Eccentricity.
Definition: convertdef.h:540
rvector a
2nd derivative: Alpha - acceleration
Definition: convertdef.h:483
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
int32_t kep2eci(kepstruc &kep, cartpos &eci)
Definition: convertlib.cpp:2878
void gauss_jackson_init_eci(gj_handle &gjh, uint32_t order, int32_t mode, double dt, double utc, cartpos ipos, qatt iatt, physicsstruc &physics, locstruc &loc)
Initialize Gauss-Jackson orbit using ECI state vector.
Definition: physicslib.cpp:2479
cartpos geoc
Definition: convertdef.h:739
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
qatt lvlh
Definition: convertdef.h:827
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
static double initialutc
Definition: physicslib.cpp:43
int32_t pos_clear(locstruc *loc)
Initialize posstruc.
Definition: convertlib.cpp:77
attstruc att
attstruc for this time.
Definition: convertdef.h:883
qatt icrf
Definition: convertdef.h:830
int32_t pos_geoc(locstruc *loc)
Set Geocentric position.
Definition: convertlib.cpp:366
double raan
Right Ascension of the Ascending Node in radians.
Definition: convertdef.h:549
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
Classical elements structure.
Definition: convertdef.h:529
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:485
#define REARTHM
SI Radius of Earth.
Definition: convertdef.h:60
const double D2PI
Double precision 2*PI.
Definition: math/constants.h:16
double ap
Argument of Perigee.
Definition: convertdef.h:551
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
double dt
Time step in seconds.
Definition: jsondef.h:3414
double i
Orbital Inclination in radians.
Definition: convertdef.h:547
cartpos eci
Definition: convertdef.h:737
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
double a
Semi-Major Axis in meters.
Definition: convertdef.h:538
int32_t mode
Definition: jsondef.h:3436
const double DPI
Double precision PI.
Definition: math/constants.h:14
double ea
Eccentric Anomoly.
Definition: convertdef.h:559
double utc
Simulated starting time in MJD.
Definition: jsondef.h:3418
double dtj
Time step in Julian days.
Definition: jsondef.h:3416
int32_t att_lvlh(locstruc *loc)
Definition: convertlib.cpp:2064
void gauss_jackson_setup(gj_handle &gjh, uint32_t order, double utc, double &dt)
Prepare for Gauss-Jackson integration.
Definition: physicslib.cpp:2219
locstruc gauss_jackson_converge_orbit ( gj_handle gjh,
physicsstruc physics 
)
2762 {
2763  uint32_t c_cnt, cflag=0, k, n, i;
2764  rvector oldsa;
2765 
2766  c_cnt = 0;
2767  do
2768  {
2769  gjh.step[gjh.order2].s.col[0] = gjh.step[gjh.order2].sloc.pos.eci.v.col[0]/gjh.dt;
2770  gjh.step[gjh.order2].s.col[1] = gjh.step[gjh.order2].sloc.pos.eci.v.col[1]/gjh.dt;
2771  gjh.step[gjh.order2].s.col[2] = gjh.step[gjh.order2].sloc.pos.eci.v.col[2]/gjh.dt;
2772  for (k=0; k<=gjh.order; k++)
2773  {
2774  gjh.step[gjh.order2].s.col[0] -= gjh.step[gjh.order2].b[k] * gjh.step[k].sloc.pos.eci.a.col[0];
2775  gjh.step[gjh.order2].s.col[1] -= gjh.step[gjh.order2].b[k] * gjh.step[k].sloc.pos.eci.a.col[1];
2776  gjh.step[gjh.order2].s.col[2] -= gjh.step[gjh.order2].b[k] * gjh.step[k].sloc.pos.eci.a.col[2];
2777  }
2778  for (n=1; n<=gjh.order2; n++)
2779  {
2780  gjh.step[gjh.order2+n].s.col[0] = gjh.step[gjh.order2+n-1].s.col[0] + (gjh.step[gjh.order2+n].sloc.pos.eci.a.col[0]+gjh.step[gjh.order2+n-1].sloc.pos.eci.a.col[0])/2;
2781  gjh.step[gjh.order2+n].s.col[1] = gjh.step[gjh.order2+n-1].s.col[1] + (gjh.step[gjh.order2+n].sloc.pos.eci.a.col[1]+gjh.step[gjh.order2+n-1].sloc.pos.eci.a.col[1])/2;
2782  gjh.step[gjh.order2+n].s.col[2] = gjh.step[gjh.order2+n-1].s.col[2] + (gjh.step[gjh.order2+n].sloc.pos.eci.a.col[2]+gjh.step[gjh.order2+n-1].sloc.pos.eci.a.col[2])/2;
2783  gjh.step[gjh.order2-n].s.col[0] = gjh.step[gjh.order2-n+1].s.col[0] - (gjh.step[gjh.order2-n].sloc.pos.eci.a.col[0]+gjh.step[gjh.order2-n+1].sloc.pos.eci.a.col[0])/2;
2784  gjh.step[gjh.order2-n].s.col[1] = gjh.step[gjh.order2-n+1].s.col[1] - (gjh.step[gjh.order2-n].sloc.pos.eci.a.col[1]+gjh.step[gjh.order2-n+1].sloc.pos.eci.a.col[1])/2;
2785  gjh.step[gjh.order2-n].s.col[2] = gjh.step[gjh.order2-n+1].s.col[2] - (gjh.step[gjh.order2-n].sloc.pos.eci.a.col[2]+gjh.step[gjh.order2-n+1].sloc.pos.eci.a.col[2])/2;
2786  }
2787  gjh.step[gjh.order2].ss.col[0] = gjh.step[gjh.order2].sloc.pos.eci.s.col[0]/gjh.dtsq;
2788  gjh.step[gjh.order2].ss.col[1] = gjh.step[gjh.order2].sloc.pos.eci.s.col[1]/gjh.dtsq;
2789  gjh.step[gjh.order2].ss.col[2] = gjh.step[gjh.order2].sloc.pos.eci.s.col[2]/gjh.dtsq;
2790  for (k=0; k<=gjh.order; k++)
2791  {
2792  gjh.step[gjh.order2].ss.col[0] -= gjh.step[gjh.order2].a[k] * gjh.step[k].sloc.pos.eci.a.col[0];
2793  gjh.step[gjh.order2].ss.col[1] -= gjh.step[gjh.order2].a[k] * gjh.step[k].sloc.pos.eci.a.col[1];
2794  gjh.step[gjh.order2].ss.col[2] -= gjh.step[gjh.order2].a[k] * gjh.step[k].sloc.pos.eci.a.col[2];
2795  }
2796  for (n=1; n<=gjh.order2; n++)
2797  {
2798  gjh.step[gjh.order2+n].ss.col[0] = gjh.step[gjh.order2+n-1].ss.col[0] + gjh.step[gjh.order2+n-1].s.col[0] + (gjh.step[gjh.order2+n-1].sloc.pos.eci.a.col[0])/2;
2799  gjh.step[gjh.order2+n].ss.col[1] = gjh.step[gjh.order2+n-1].ss.col[1] + gjh.step[gjh.order2+n-1].s.col[1] + (gjh.step[gjh.order2+n-1].sloc.pos.eci.a.col[1])/2;
2800  gjh.step[gjh.order2+n].ss.col[2] = gjh.step[gjh.order2+n-1].ss.col[2] + gjh.step[gjh.order2+n-1].s.col[2] + (gjh.step[gjh.order2+n-1].sloc.pos.eci.a.col[2])/2;
2801  gjh.step[gjh.order2-n].ss.col[0] = gjh.step[gjh.order2-n+1].ss.col[0] - gjh.step[gjh.order2-n+1].s.col[0] + (gjh.step[gjh.order2-n+1].sloc.pos.eci.a.col[0])/2;
2802  gjh.step[gjh.order2-n].ss.col[1] = gjh.step[gjh.order2-n+1].ss.col[1] - gjh.step[gjh.order2-n+1].s.col[1] + (gjh.step[gjh.order2-n+1].sloc.pos.eci.a.col[1])/2;
2803  gjh.step[gjh.order2-n].ss.col[2] = gjh.step[gjh.order2-n+1].ss.col[2] - gjh.step[gjh.order2-n+1].s.col[2] + (gjh.step[gjh.order2-n+1].sloc.pos.eci.a.col[2])/2;
2804  }
2805 
2806  for (n=0; n<=gjh.order; n++)
2807  {
2808  if (n == gjh.order2)
2809  continue;
2810  gjh.step[n].sb = gjh.step[n].sa = rv_zero();
2811  for (k=0; k<=gjh.order; k++)
2812  {
2813  gjh.step[n].sb.col[0] += gjh.step[n].b[k] * gjh.step[k].sloc.pos.eci.a.col[0];
2814  gjh.step[n].sa.col[0] += gjh.step[n].a[k] * gjh.step[k].sloc.pos.eci.a.col[0];
2815  gjh.step[n].sb.col[1] += gjh.step[n].b[k] * gjh.step[k].sloc.pos.eci.a.col[1];
2816  gjh.step[n].sa.col[1] += gjh.step[n].a[k] * gjh.step[k].sloc.pos.eci.a.col[1];
2817  gjh.step[n].sb.col[2] += gjh.step[n].b[k] * gjh.step[k].sloc.pos.eci.a.col[2];
2818  gjh.step[n].sa.col[2] += gjh.step[n].a[k] * gjh.step[k].sloc.pos.eci.a.col[2];
2819  }
2820  }
2821 
2822  for (n=1; n<=gjh.order2; n++)
2823  {
2824  for (i=-1; i<2; i+=2)
2825  {
2826  cflag = 0;
2827 
2828  // Save current acceleration for comparison with next iteration
2829  oldsa.col[0] = gjh.step[gjh.order2+i*n].sloc.pos.eci.a.col[0];
2830  oldsa.col[1] = gjh.step[gjh.order2+i*n].sloc.pos.eci.a.col[1];
2831  oldsa.col[2] = gjh.step[gjh.order2+i*n].sloc.pos.eci.a.col[2];
2832 
2833  // Calculate new probable position and velocity
2834  gjh.step[gjh.order2+i*n].sloc.pos.eci.v.col[0] = gjh.dt * (gjh.step[gjh.order2+i*n].s.col[0] + gjh.step[gjh.order2+i*n].sb.col[0]);
2835  gjh.step[gjh.order2+i*n].sloc.pos.eci.v.col[1] = gjh.dt * (gjh.step[gjh.order2+i*n].s.col[1] + gjh.step[gjh.order2+i*n].sb.col[1]);
2836  gjh.step[gjh.order2+i*n].sloc.pos.eci.v.col[2] = gjh.dt * (gjh.step[gjh.order2+i*n].s.col[2] + gjh.step[gjh.order2+i*n].sb.col[2]);
2837  gjh.step[gjh.order2+i*n].sloc.pos.eci.s.col[0] = gjh.dtsq * (gjh.step[gjh.order2+i*n].ss.col[0] + gjh.step[gjh.order2+i*n].sa.col[0]);
2838  gjh.step[gjh.order2+i*n].sloc.pos.eci.s.col[1] = gjh.dtsq * (gjh.step[gjh.order2+i*n].ss.col[1] + gjh.step[gjh.order2+i*n].sa.col[1]);
2839  gjh.step[gjh.order2+i*n].sloc.pos.eci.s.col[2] = gjh.dtsq * (gjh.step[gjh.order2+i*n].ss.col[2] + gjh.step[gjh.order2+i*n].sa.col[2]);
2840 
2841  // Perform conversions between different systems
2842  gjh.step[gjh.order2+i*n].sloc.pos.eci.pass++;
2843  pos_eci(&gjh.step[gjh.order2+i*n].sloc);
2844  att_icrf2lvlh(&gjh.step[gjh.order2+i*n].sloc);
2845  // eci2earth(&gjh.step[gjh.order2+i*n].sloc.pos,&gjh.step[gjh.order2+i*n].sloc.att);
2846 
2847  // Calculate acceleration at new position
2848  pos_accel(physics, gjh.step[gjh.order2+i*n].sloc);
2849  // hardware_init_eci(cinfo,gjh.step[gjh.order2+i*n].sloc);
2850 
2851  // Compare acceleration at new position to previous iteration
2852  if (fabs(oldsa.col[0]-gjh.step[gjh.order2+i*n].sloc.pos.eci.a.col[0])>1e-14 || fabs(oldsa.col[1]-gjh.step[gjh.order2+i*n].sloc.pos.eci.a.col[1])>1e-14 || fabs(oldsa.col[2]-gjh.step[gjh.order2+i*n].sloc.pos.eci.a.col[2])>1e-14)
2853  cflag = 1;
2854  }
2855  }
2856  c_cnt++;
2857  } while (c_cnt<10 && cflag);
2858 
2859  return gjh.step[gjh.order].sloc;
2860 }
Definition: eci2kep_test.cpp:33
3 element generic row vector
Definition: vector.h:53
int i
Definition: rw_test.cpp:37
double dt
Definition: physicsdef.h:107
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
uint32_t order
Definition: physicsdef.h:109
uint32_t order2
Definition: physicsdef.h:110
double dtsq
Definition: physicsdef.h:108
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
double col[3]
Definition: vector.h:55
vector< gjstruc > step
Definition: physicsdef.h:111
int32_t pos_accel(physicsstruc &physics, locstruc &loc)
Position acceleration.
Definition: physicslib.cpp:1553
void gauss_jackson_converge_hardware ( gj_handle gjh,
physicsstruc physics 
)
2863 {
2864  for (uint16_t i=0; i<=gjh.order; ++i)
2865  {
2866  // simulate_hardware(cinfo, gjh.step[i].sloc);
2867  att_accel(physics, gjh.step[i].sloc);
2868  }
2869 }
int i
Definition: rw_test.cpp:37
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
uint32_t order
Definition: physicsdef.h:109
vector< gjstruc > step
Definition: physicsdef.h:111
vector<locstruc> gauss_jackson_propagate ( gj_handle gjh,
physicsstruc physics,
locstruc loc,
double  mjd 
)
2872 {
2873  uint32_t i,chunks , astep;
2874  uint32_t j, k;
2875  // static quaternion qs[2]={{{0.,0.,0.},0.}};
2876  // static rvector alpha[2] = {{{0.,0.,0.}}};
2877  // static rvector omega[2] = {{{0.,0.,0.}}};
2878  quaternion q1, dsq, q2;
2879  dem_pixel val;
2880  rvector normal, unitv, unitx, unitp, unitp1, unitp2;
2881  static rvector lunitp1 = {.1,.1,0.};
2882  double angle;
2883  uvector utemp{};
2884  double dtsave;
2885  double dtuse;
2886  rmatrix tskew;
2887  uvector tvector1{};
2888  matrix2d tmatrix2;
2889  rvector tvector;
2890  vector <locstruc> locvec;
2891 
2892  // Initial location
2893  locvec.push_back(loc);
2894 
2895  // Don't bother if too low
2896  if (gjh.step[gjh.order].sloc.pos.geod.s.h < 100.)
2897  {
2898  return locvec;
2899  }
2900  // if (qs[0].w == 0.)
2901  // {
2902  // qs[0] = qs[1] = loc.att.icrf.s;
2903  // alpha[0] = alpha[1] = loc.att.icrf.a;
2904  // omega[0] = omega[1] = loc.att.icrf.v;
2905  // }
2906  // Return immediately if we are trying to propagate earlier but dt is positive or vice versa
2907  if ((tomjd < gjh.step[gjh.order].sloc.utc && physics.dt > 0.) || (tomjd > gjh.step[gjh.order].sloc.utc && physics.dt < 0.))
2908  {
2909  return locvec;
2910  }
2911  chunks = (uint32_t)(.5 + 86400.*(tomjd - gjh.step[gjh.order].sloc.utc)/physics.dt);
2912  if (chunks > 100000)
2913  {
2914  chunks = 100000;
2915 // dtuse = 86400.*(tomjd - gjh.step[gjh.order].sloc.utc) / 100000;
2916  }
2917 // else
2918 // {
2919  dtuse = physics.dt;
2920 // }
2921 
2922  for (i=0; i<chunks; i++)
2923  {
2924  if (gjh.step[gjh.order].sloc.pos.geod.s.h < 100.)
2925  {
2926  break;
2927  }
2928 
2929  gjh.step[gjh.order+1].sloc.pos.eci.utc = gjh.step[gjh.order+1].sloc.utc = gjh.step[gjh.order].sloc.utc + (dtuse)/86400.;
2930 
2931  // Calculate S(order/2+1)
2932  gjh.step[gjh.order+1].ss.col[0] = gjh.step[gjh.order].ss.col[0] + gjh.step[gjh.order].s.col[0] + gjh.step[gjh.order].sloc.pos.eci.a.col[0]/2.;
2933  gjh.step[gjh.order+1].ss.col[1] = gjh.step[gjh.order].ss.col[1] + gjh.step[gjh.order].s.col[1] + gjh.step[gjh.order].sloc.pos.eci.a.col[1]/2.;
2934  gjh.step[gjh.order+1].ss.col[2] = gjh.step[gjh.order].ss.col[2] + gjh.step[gjh.order].s.col[2] + gjh.step[gjh.order].sloc.pos.eci.a.col[2]/2.;
2935 
2936  // Calculate Sum(order/2+1) for a and b
2937  gjh.step[gjh.order+1].sb = gjh.step[gjh.order+1].sa = rv_zero();
2938  for (k=0; k<=gjh.order; k++)
2939  {
2940  gjh.step[gjh.order+1].sb.col[0] += gjh.step[gjh.order+1].b[k] * gjh.step[k].sloc.pos.eci.a.col[0];
2941  gjh.step[gjh.order+1].sa.col[0] += gjh.step[gjh.order+1].a[k] * gjh.step[k].sloc.pos.eci.a.col[0];
2942  gjh.step[gjh.order+1].sb.col[1] += gjh.step[gjh.order+1].b[k] * gjh.step[k].sloc.pos.eci.a.col[1];
2943  gjh.step[gjh.order+1].sa.col[1] += gjh.step[gjh.order+1].a[k] * gjh.step[k].sloc.pos.eci.a.col[1];
2944  gjh.step[gjh.order+1].sb.col[2] += gjh.step[gjh.order+1].b[k] * gjh.step[k].sloc.pos.eci.a.col[2];
2945  gjh.step[gjh.order+1].sa.col[2] += gjh.step[gjh.order+1].a[k] * gjh.step[k].sloc.pos.eci.a.col[2];
2946  }
2947 
2948  // Calculate pos.v(order/2+1)
2949  gjh.step[gjh.order+1].sloc.pos.eci.v.col[0] = gjh.dt * (gjh.step[gjh.order].s.col[0] + gjh.step[gjh.order].sloc.pos.eci.a.col[0]/2. + gjh.step[gjh.order+1].sb.col[0]);
2950  gjh.step[gjh.order+1].sloc.pos.eci.v.col[1] = gjh.dt * (gjh.step[gjh.order].s.col[1] + gjh.step[gjh.order].sloc.pos.eci.a.col[1]/2. + gjh.step[gjh.order+1].sb.col[1]);
2951  gjh.step[gjh.order+1].sloc.pos.eci.v.col[2] = gjh.dt * (gjh.step[gjh.order].s.col[2] + gjh.step[gjh.order].sloc.pos.eci.a.col[2]/2. + gjh.step[gjh.order+1].sb.col[2]);
2952 
2953  // Calculate pos.s(order/2+1)
2954  gjh.step[gjh.order+1].sloc.pos.eci.s.col[0] = gjh.dtsq * (gjh.step[gjh.order+1].ss.col[0] + gjh.step[gjh.order+1].sa.col[0]);
2955  gjh.step[gjh.order+1].sloc.pos.eci.s.col[1] = gjh.dtsq * (gjh.step[gjh.order+1].ss.col[1] + gjh.step[gjh.order+1].sa.col[1]);
2956  gjh.step[gjh.order+1].sloc.pos.eci.s.col[2] = gjh.dtsq * (gjh.step[gjh.order+1].ss.col[2] + gjh.step[gjh.order+1].sa.col[2]);
2957  gjh.step[gjh.order+1].sloc.pos.eci.pass++;
2958  pos_eci(&gjh.step[gjh.order+1].sloc);
2959 
2960  // Calculate att.s(order/2+1) + hardware
2961  gjh.step[gjh.order+1].sloc.att.icrf = gjh.step[gjh.order].sloc.att.icrf;
2962  gjh.step[gjh.order+1].sloc.att.icrf.utc = gjh.step[gjh.order].sloc.utc;
2963  switch (physics.mode)
2964  {
2965  case 0:
2966  // Calculate att.v(order/2+1)
2967  astep = 1 + (length_rv(gjh.step[gjh.order+1].sloc.att.icrf.v) * dtuse) / .01;
2968  if (astep > 1000)
2969  {
2970  astep = 1000;
2971  }
2972  dtsave = dtuse;
2973  dtuse /= astep;
2974  gjh.step[gjh.order+1].sloc.utc = gjh.step[gjh.order].sloc.utc;
2975  // simulate_hardware(cinfo, gjh.step[gjh.order+1].sloc);
2976  att_accel(physics, gjh.step[gjh.order+1].sloc);
2977  for (k=0; k<astep; k++)
2978  {
2979  tvector = irotate(gjh.step[gjh.order+1].sloc.att.icrf.s,rv_smult(dtuse,gjh.step[gjh.order+1].sloc.att.icrf.v));
2980  tskew = rm_skew(tvector);
2981  tmatrix2.rows = tmatrix2.cols = 4;
2982  for (int l=0; l<3; ++l)
2983  {
2984  tmatrix2.array[3][l] = -tvector.col[l];
2985  tmatrix2.array[l][3] = tvector.col[l];
2986  for (int m=0; m<3; m++)
2987  {
2988  tmatrix2.array[l][m] = -tskew.row[l].col[m];
2989  }
2990  }
2991  tmatrix2.array[3][3] = 0.;
2992  tvector1.m1.cols = 4;
2993  tvector1.q = gjh.step[gjh.order+1].sloc.att.icrf.s;
2994  tvector1.m1 = m1_smult(.5,m1_mmult(tmatrix2,tvector1.m1));
2995  gjh.step[gjh.order+1].sloc.att.icrf.s = q_add(gjh.step[gjh.order+1].sloc.att.icrf.s,tvector1.q);
2996 
2997  // q1 = q_axis2quaternion_rv(rv_smult(dtuse,gjh.step[gjh.order+1].sloc.att.icrf.v));
2998  // gjh.step[gjh.order+1].sloc.att.icrf.s = q_fmult(q1,gjh.step[gjh.order+1].sloc.att.icrf.s);
2999  normalize_q(&gjh.step[gjh.order+1].sloc.att.icrf.s);
3000 
3001  // Calculate new v from da
3002  gjh.step[gjh.order+1].sloc.att.icrf.v = rv_add(gjh.step[gjh.order+1].sloc.att.icrf.v,rv_smult(dtuse,gjh.step[gjh.order+1].sloc.att.icrf.a));
3003  gjh.step[gjh.order+1].sloc.utc += (dtuse)/86400.;
3004  ++gjh.step[gjh.order+1].sloc.att.icrf.pass;
3005  att_icrf(&gjh.step[gjh.order+1].sloc);
3006  }
3007  dtuse = dtsave;
3008  break;
3009  case 1:
3010  // Force LVLH
3011  gjh.step[gjh.order+1].sloc.att.lvlh.utc = gjh.step[gjh.order+1].sloc.utc;
3012  gjh.step[gjh.order+1].sloc.att.lvlh.s = q_eye();
3013  gjh.step[gjh.order+1].sloc.att.lvlh.v = rv_zero();
3014  att_lvlh2icrf(&gjh.step[gjh.order+1].sloc);
3015  break;
3016  case 2:
3017  // Force surface normal (rover)
3018  gjh.step[gjh.order+1].sloc.att.topo.v = gjh.step[gjh.order+1].sloc.att.topo.a = rv_zero();
3019  switch (gjh.step[gjh.order+1].sloc.pos.extra.closest)
3020  {
3021  case COSMOS_EARTH:
3022  default:
3023  val = map_dem_pixel(COSMOS_EARTH,gjh.step[gjh.order+1].sloc.pos.geod.s.lon,gjh.step[gjh.order+1].sloc.pos.geod.s.lat,1./REARTHM);
3024  for (j=0; j<3; j++)
3025  {
3026  normal.col[j] = val.nmap[j];
3027  }
3028  unitv = rv_zero();
3029  unitv.col[0] = gjh.step[gjh.order+1].sloc.pos.geod.v.lon / cos(gjh.step[gjh.order+1].sloc.pos.geod.s.lat);
3030  unitv.col[1] = gjh.step[gjh.order+1].sloc.pos.geod.v.lat;
3031  break;
3032  case COSMOS_MOON:
3033  val = map_dem_pixel(COSMOS_MOON,gjh.step[gjh.order+1].sloc.pos.selg.s.lon,gjh.step[gjh.order+1].sloc.pos.selg.s.lat,1./RMOONM);
3034  for (j=0; j<3; j++)
3035  {
3036  normal.col[j] = -val.nmap[j];
3037  }
3038  unitv = rv_zero();
3039  unitv.col[0] = gjh.step[gjh.order+1].sloc.pos.selg.v.lon / cos(gjh.step[gjh.order+1].sloc.pos.selg.s.lat);
3040  unitv.col[1] = gjh.step[gjh.order+1].sloc.pos.selg.v.lat;
3041  break;
3042  }
3043  q1 = q_drotate_between_rv(rv_unitz(),normal);
3044  unitx = rv_cross(normal,rv_unity());
3045  unitx = irotate(q1,unitx);
3046  q2 = q_drotate_between_rv(unitx,unitv);
3047  // gjh.step[gjh.order+1].sloc.att.topo.s = q_fmult(q2,q1);
3048  gjh.step[gjh.order+1].sloc.att.topo.s = q1;
3049  gjh.step[gjh.order+1].sloc.att.topo.utc = gjh.step[gjh.order+1].sloc.pos.utc+1.e8;
3050  gjh.step[gjh.order+1].sloc.att.topo.pass++;
3051  att_topo(&gjh.step[gjh.order+1].sloc);
3052  break;
3053  case 3:
3054  gjh.step[gjh.order+1].sloc.att.icrf.utc = gjh.step[gjh.order+1].sloc.utc;
3055  q1 = gjh.step[gjh.order+1].sloc.att.icrf.s;
3056  gjh.step[gjh.order+1].sloc.att.icrf.s = q_drotate_between_rv(physics.thrust.to_rv(),rv_unitz());
3057  dsq = q_sub(gjh.step[gjh.order+1].sloc.att.icrf.s,q1);
3058  angle = 2. * atan(length_q(dsq)/2.);
3059  q2 = q_smult(1./cos(angle),gjh.step[gjh.order+1].sloc.att.icrf.s);
3060  dsq = q_sub(q2,q1);
3061  utemp.q = q_smult(2.,q_fmult(q_conjugate(q1),dsq));
3062  gjh.step[gjh.order+1].sloc.att.icrf.v = utemp.r;
3063  att_icrf2lvlh(&gjh.step[gjh.order+1].sloc);
3064  break;
3065  case 4:
3066  gjh.step[gjh.order+1].sloc.att.selc.utc = gjh.step[gjh.order+1].sloc.utc;
3067  unitp1.col[0] += .1*(gjh.step[gjh.order+1].sloc.pos.selg.v.lon-unitp1.col[0]);
3068  unitp1.col[1] += .1*(gjh.step[gjh.order+1].sloc.pos.selg.v.lat-unitp1.col[1]);
3069  unitp1.col[2] = 0.;
3070  if (length_rv(unitp1) < 1e-9)
3071  unitp1 = lunitp1;
3072  else
3073  lunitp1 = unitp1;
3074  q1 = q_drotate_between_rv(rv_unitx(),unitp1);
3075  val = map_dem_pixel(COSMOS_MOON,gjh.step[gjh.order+1].sloc.pos.selg.s.lon,gjh.step[gjh.order+1].sloc.pos.selg.s.lat,.0003);
3076  unitp2.col[0] += .1*(val.nmap[0]-unitp2.col[0]);
3077  unitp2.col[1] += .1*(val.nmap[1]-unitp2.col[1]);
3078  unitp2.col[2] += .1*(val.nmap[2]-unitp2.col[2]);
3079  q2 = q_drotate_between_rv(irotate(q1,rv_unitz()),unitp2);
3080  gjh.step[gjh.order+1].sloc.att.selc.s = q_conjugate(q_fmult(q2,q1));
3081  gjh.step[gjh.order+1].sloc.att.selc.v = rv_zero();
3082  att_selc2icrf(&gjh.step[gjh.order+1].sloc);
3083  break;
3084  case 5:
3085  gjh.step[gjh.order+1].sloc.att.geoc.utc = gjh.step[gjh.order+1].sloc.utc;
3086  angle = 2.*acos(gjh.step[gjh.order+1].sloc.att.geoc.s.w);
3087  gjh.step[gjh.order+1].sloc.att.geoc.s = q_change_around_z(angle+.2*D2PI*dtuse);
3088  gjh.step[gjh.order+1].sloc.att.geoc.v = rv_smult(.2*D2PI,rv_unitz());
3089  att_geoc2icrf(&gjh.step[gjh.order+1].sloc);
3090  att_planec2lvlh(&gjh.step[gjh.order+1].sloc);
3091  break;
3092  case 6:
3093  case 7:
3094  case 8:
3095  case 9:
3096  case 10:
3097  case 11:
3098  // gjh.step[gjh.order+1].sloc.att.icrf.s = q_drotate_between_rv(cinfo->pieces[physics.mode-2].normal,rv_smult(-1.,gjh.step[gjh.order+1].sloc.pos.icrf.s));
3099  gjh.step[gjh.order+1].sloc.att.icrf.v = rv_zero();
3100  att_icrf2lvlh(&gjh.step[gjh.order+1].sloc);
3101  break;
3102  case 12:
3103  angle = (1440.*(gjh.step[gjh.order+1].sloc.utc - initialutc) - (int)(1440.*(gjh.step[gjh.order+1].sloc.utc - initialutc))) * 2.*DPI;
3104  unitx = unitp = rv_zero();
3105  unitx.col[0] = 1.;
3106  unitp.col[0] = cos(angle);
3107  unitp.col[1] = sin(angle);
3108  gjh.step[gjh.order+1].sloc.att.lvlh.s = q_drotate_between_rv(unitp,unitx);
3109  gjh.step[gjh.order+1].sloc.att.lvlh.v = rv_zero();
3110  gjh.step[gjh.order+1].sloc.att.lvlh.v.col[2] = 2.*DPI/1440.;
3111  att_lvlh2icrf(&gjh.step[gjh.order+1].sloc);
3112  break;
3113  }
3114  // simulate_hardware(cinfo, gjh.step[gjh.order+1].sloc);
3115  att_accel(physics, gjh.step[gjh.order+1].sloc);
3116  // Perform positional and attitude accelerations at new position
3117  pos_accel(physics, gjh.step[gjh.order+1].sloc);
3118 
3119  // Calculate s(order/2+1)
3120  gjh.step[gjh.order+1].s.col[0] = gjh.step[gjh.order].s.col[0] + (gjh.step[gjh.order].sloc.pos.eci.a.col[0]+gjh.step[gjh.order+1].sloc.pos.eci.a.col[0])/2.;
3121  gjh.step[gjh.order+1].s.col[1] = gjh.step[gjh.order].s.col[1] + (gjh.step[gjh.order].sloc.pos.eci.a.col[1]+gjh.step[gjh.order+1].sloc.pos.eci.a.col[1])/2.;
3122  gjh.step[gjh.order+1].s.col[2] = gjh.step[gjh.order].s.col[2] + (gjh.step[gjh.order].sloc.pos.eci.a.col[2]+gjh.step[gjh.order+1].sloc.pos.eci.a.col[2])/2.;
3123 
3124  // Shift everything over 1
3125  for (j=0; j<=gjh.order; j++)
3126  gjh.step[j] = gjh.step[j+1];
3127 
3128  // Add latest calculation
3129  locvec.push_back(gjh.step[gjh.order].sloc);
3130 
3131  }
3132 
3133  loc = gjh.step[gjh.order].sloc;
3134  return locvec;
3135 }
matrix1d m1_smult(double number, matrix1d row)
Multiply 1D matrix by a scalar.
Definition: matrix.cpp:979
Quaternion/Rvector Union.
Definition: mathlib.h:155
float nmap[3]
Definition: demlib.h:85
rmatrix rm_skew(rvector row)
Create skew symmetric rmatrix from rvector.
Definition: matrix.cpp:857
Definition: eci2kep_test.cpp:33
quaternion q_sub(quaternion a, quaternion b)
Subtract two quaternions.
Definition: vector.cpp:1186
rvector rv_add(rvector a, rvector b)
Add two row vectors.
Definition: vector.cpp:299
3 element generic row vector
Definition: vector.h:53
int i
Definition: rw_test.cpp:37
Vector thrust
Definition: jsondef.h:3447
double length_rv(rvector v)
Length of row vector.
Definition: vector.cpp:748
double dt
Definition: physicsdef.h:107
Quaternion, scalar last, using x, y, z.
Definition: vector.h:402
quaternion q_conjugate(quaternion q)
Definition: vector.cpp:1010
rvector to_rv()
Convert from cvector.
Definition: vector.cpp:1638
int32_t att_icrf(locstruc *loc)
Definition: convertlib.cpp:1836
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
matrix1d m1_mmult(matrix2d Matrix, matrix1d Vector)
Multiply matrix1d by matrix2d.
Definition: matrix.cpp:1041
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
quaternion q_fmult(rvector r1, quaternion q2)
rvector quaternion multiply
Definition: vector.cpp:1079
static double initialutc
Definition: physicslib.cpp:43
rvector rv_unity(double scale)
Scaled y row vector.
Definition: vector.cpp:129
double array[4][4]
Elements.
Definition: matrix.h:160
quaternion q_smult(double a, quaternion b)
Multiply quaternion by scalar.
Definition: vector.cpp:1151
double length_q(quaternion q)
Length of quaternion.
Definition: vector.cpp:1329
quaternion q_drotate_between_rv(rvector from, rvector to)
Create rotation quaternion from 2 row vectors.
Definition: mathlib.cpp:81
void normalize_q(quaternion *q)
Definition: vector.cpp:961
dem_pixel map_dem_pixel(int body, double lon, double lat, double res)
Height in DEM.
Definition: demlib.cpp:342
uint16_t rows
Number of rows.
Definition: matrix.h:156
3x3 element generic matrix
Definition: matrix.h:41
int32_t att_planec2lvlh(locstruc *loc)
Convert ITRS attitude to LVLH attitude.
Definition: convertlib.cpp:1863
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
quaternion q_change_around_z(double angle)
Rotation quaternion for Z axis.
Definition: vector.cpp:1461
int32_t att_geoc2icrf(locstruc *loc)
Definition: convertlib.cpp:1639
nxm element 2D matrix
Definition: matrix.h:153
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
#define RMOONM
SI Radius of Moon.
Definition: convertdef.h:58
rvector rv_unitz(double scale)
Scaled z row vector.
Definition: vector.cpp:140
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
int32_t att_selc2icrf(locstruc *loc)
Definition: convertlib.cpp:1760
uint32_t order
Definition: physicsdef.h:109
#define COSMOS_MOON
Definition: convertdef.h:144
#define COSMOS_EARTH
Definition: convertdef.h:137
#define REARTHM
SI Radius of Earth.
Definition: convertdef.h:60
double dtsq
Definition: physicsdef.h:108
const double D2PI
Double precision 2*PI.
Definition: math/constants.h:16
uint16_t cols
Number of elements.
Definition: matrix.h:158
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
double col[3]
Definition: vector.h:55
double dt
Time step in seconds.
Definition: jsondef.h:3414
rvector irotate(quaternion q, rvector v)
Indirectly rotate a row vector using a quaternion.
Definition: mathlib.cpp:2308
vector< gjstruc > step
Definition: physicsdef.h:111
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
int32_t mode
Definition: jsondef.h:3436
const double DPI
Double precision PI.
Definition: math/constants.h:14
Location value.
Definition: demlib.h:82
rvector rv_unitx(double scale)
Scaled x row vector.
Definition: vector.cpp:118
int32_t att_topo(locstruc *loc)
Definition: convertlib.cpp:2252
rvector row[3]
Definition: matrix.h:43
rvector rv_cross(rvector a, rvector b)
Take cross product of two row vectors.
Definition: vector.cpp:363
quaternion q_add(quaternion a, quaternion b)
Add two quaternions.
Definition: vector.cpp:1168
int32_t pos_accel(physicsstruc &physics, locstruc &loc)
Position acceleration.
Definition: physicslib.cpp:1553
int orbit_propagate ( cosmosstruc root,
double  mjd 
)

Load TLE's from file.

3260 {
3261  cartpos npos;
3262  int32_t chunks, i, iretn;
3263  double nutc;
3264 
3265  chunks = (uint32_t)(.5 + 86400.*(utc-cinfo->node.loc.utc)/cinfo->node.phys.dt);
3266  if (chunks > 100000)
3267  {
3268  chunks = 100000;
3269  }
3270  nutc = cinfo->node.loc.utc;
3271  for (i=0; i<chunks; i++)
3272  {
3273  nutc += cinfo->node.phys.dt/86400.;
3274  switch (orbitfile[0])
3275  {
3276  case 's':
3277  if ((iretn=stk2eci(nutc,stkhandle,npos)) < 0)
3278  return iretn;
3279  break;
3280  case 't':
3281  if ((iretn=lines2eci(nutc,cinfo->tle,npos)) < 0)
3282  return iretn;
3283  break;
3284  default:
3285  return (ORBIT_ERROR_NOTSUPPORTED);
3286  break;
3287  }
3288  update_eci(cinfo,nutc,npos);
3289 
3290  }
3291 
3292 
3293  cinfo->timestamp = currentmjd();
3294  return 0;
3295 }
int update_eci(cosmosstruc *cinfo, double utc, cartpos pos)
Definition: physicslib.cpp:3297
static string orbitfile
Definition: physicslib.cpp:44
int i
Definition: rw_test.cpp:37
Cartesian full position structure.
Definition: convertdef.h:158
int iretn
Definition: rw_test.cpp:37
#define ORBIT_ERROR_NOTSUPPORTED
Definition: cosmos-errno.h:140
static stkstruc stkhandle
Definition: physicslib.cpp:45
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
int lines2eci(double utc, vector< tlestruc >lines, cartpos &eci)
Return position from TLE set.
Definition: convertlib.cpp:3155
int stk2eci(double utc, stkstruc &stk, cartpos &eci)
ECI from STK data.
Definition: convertlib.cpp:3842
int orbit_init ( int32_t  mode,
double  dt,
double  utc,
string  ofile,
cosmosstruc cinfo 
)

Initialize orbit from orbital data.

Initializes satellite structure using orbital data

Parameters
modeThe style of propagation. Zero is free propagation.
dtStep size in seconds
utcInitial step time as UTC in Modified Julian Days. If set to 0., first time in the orbital data will be used.
ofileName of the file containing orbital data. Two Line Element set if first letter is 't', STK data if first letter is 's'.
cinfoReference to cosmosstruc to use.
Returns
Returns 0 if succsessful, otherwise negative error.
3151 {
3152  int32_t iretn;
3153  tlestruc tline;
3154 
3155  // Munge time step to fit local granularity
3156  dt = 86400.*((utc + dt/86400.)-utc);
3157 
3158  cinfo->node.phys.dt = dt;
3159  cinfo->node.phys.dtj = cinfo->node.phys.dt/86400.;
3160  cinfo->node.phys.mode = mode;
3161 
3162  pos_clear(cinfo->node.loc);
3163 
3164  switch (ofile[0])
3165  {
3166  case 's':
3167  if ((iretn=load_stk(ofile,stkhandle)) < 2)
3168  return iretn;
3169  if (utc == 0.)
3170  {
3171  utc = stkhandle.pos[1].utc;
3172  }
3173  if ((iretn=stk2eci(utc,stkhandle,cinfo->node.loc.pos.eci)) < 0)
3174  return iretn;
3175  break;
3176  case 't':
3177  if ((iretn=load_lines(ofile, cinfo->tle)) < 0)
3178  return iretn;
3179  if (utc == 0.)
3180  {
3181  tline = get_line(0, cinfo->tle);
3182  utc = tline.utc;
3183  }
3184  if ((iretn=lines2eci(utc,cinfo->tle,cinfo->node.loc.pos.eci)) < 0)
3185  return iretn;
3186  break;
3187  default:
3188  return (ORBIT_ERROR_NOTSUPPORTED);
3189  break;
3190  }
3191 
3192  orbitfile = ofile;
3193  cinfo->node.loc.pos.eci.pass++;
3194  pos_eci(&cinfo->node.loc);
3195 
3196  // Initial attitude
3197  cinfo->node.phys.ftorque = rv_zero();
3198  switch (cinfo->node.phys.mode)
3199  {
3200  case 0:
3201  cinfo->node.loc.att.icrf.utc = cinfo->node.loc.utc;
3202  // cinfo->node.loc.att.icrf.s = q_eye();
3203  // cinfo->node.loc.att.icrf.v = rv_smult(1.,rv_unitz());
3204  att_icrf2lvlh(&cinfo->node.loc);
3205  break;
3206  case 1:
3207  cinfo->node.loc.att.lvlh.utc = cinfo->node.loc.utc;
3208  cinfo->node.loc.att.lvlh.s = q_eye();
3209  cinfo->node.loc.att.lvlh.v = rv_zero();
3210  att_lvlh2icrf(&cinfo->node.loc);
3211  break;
3212  case 2:
3213  cinfo->node.loc.att.topo.utc = cinfo->node.loc.utc;
3214  cinfo->node.loc.att.topo.s = q_eye();
3215  cinfo->node.loc.att.topo.v = rv_zero();
3216  cinfo->node.loc.att.topo.pass++;
3217  att_topo(&cinfo->node.loc);
3218  break;
3219  case 3:
3220  cinfo->node.loc.att.lvlh.utc = cinfo->node.loc.utc;
3221  cinfo->node.loc.att.lvlh.s = q_eye();
3222  cinfo->node.loc.att.lvlh.v = rv_zero();
3223  att_lvlh2icrf(&cinfo->node.loc);
3224  break;
3225  case 4:
3226  break;
3227  case 5:
3228  cinfo->node.loc.att.geoc.utc = cinfo->node.loc.utc;
3229  cinfo->node.loc.att.geoc.s = q_eye();
3230  cinfo->node.loc.att.geoc.v = rv_smult(.2*D2PI,rv_unitz());
3231  att_geoc2icrf(&cinfo->node.loc);
3232  att_planec2lvlh(&cinfo->node.loc);
3233  break;
3234  case 6:
3235  case 7:
3236  case 8:
3237  case 9:
3238  case 10:
3239  case 11:
3240  case 12:
3241  cinfo->node.loc.att.icrf.s = q_drotate_between_rv(cinfo->faces[abs(cinfo->pieces[cinfo->node.phys.mode-2].face_idx[0])].normal.to_rv(),rv_smult(-1.,cinfo->node.loc.pos.icrf.s));
3242  cinfo->node.loc.att.icrf.v = rv_zero();
3243  att_icrf2lvlh(&cinfo->node.loc);
3244  break;
3245  }
3246 
3247 
3248  // Initialize hardware
3249  hardware_init_eci(cinfo,cinfo->node.loc);
3250  att_accel(cinfo->node.phys, cinfo->node.loc);
3251  // groundstations(cinfo,&cinfo->node.loc);
3252 
3253  cinfo->node.phys.utc = cinfo->node.loc.utc;
3254 
3255  cinfo->timestamp = currentmjd();
3256  return 0;
3257 }
double timestamp
Timestamp for last change to data.
Definition: jsondef.h:4202
vector< facestruc > faces
Vector of all faces in node.
Definition: jsondef.h:4229
vector< tlestruc > tle
Array of Two Line Elements.
Definition: jsondef.h:4259
qatt geoc
Definition: convertdef.h:828
In units for the SGP4 propogator (not NORAD TLE itself).
Definition: convertdef.h:921
cposstruc * pos
Array of positions.
Definition: convertdef.h:1006
ElapsedTime dt
Definition: agent_file3.cpp:183
static string orbitfile
Definition: physicslib.cpp:44
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:170
int iretn
Definition: rw_test.cpp:37
Vector ftorque
Definition: jsondef.h:3437
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
int32_t att_lvlh2icrf(locstruc *loc)
Convert LVLH attitude to ICRF attitude.
Definition: convertlib.cpp:2035
qatt lvlh
Definition: convertdef.h:827
rvector v
1st derivative: Omega - angular velocity
Definition: convertdef.h:481
rvector rv_smult(double a, rvector b)
Multiply row vector by scalar.
Definition: vector.cpp:266
nodestruc node
Structure for summary information in node.
Definition: jsondef.h:4220
double utc
Definition: convertdef.h:477
int32_t pos_clear(locstruc *loc)
Initialize posstruc.
Definition: convertlib.cpp:77
rvector s
Location.
Definition: convertdef.h:163
quaternion q_drotate_between_rv(rvector from, rvector to)
Create rotation quaternion from 2 row vectors.
Definition: mathlib.cpp:81
attstruc att
attstruc for this time.
Definition: convertdef.h:883
double utc
UTC as Modified Julian Day.
Definition: convertdef.h:218
int32_t att_planec2lvlh(locstruc *loc)
Convert ITRS attitude to LVLH attitude.
Definition: convertlib.cpp:1863
#define ORBIT_ERROR_NOTSUPPORTED
Definition: cosmos-errno.h:140
void att_accel(physicsstruc &physics, locstruc &loc)
Attitude acceleration.
Definition: physicslib.cpp:1493
qatt icrf
Definition: convertdef.h:830
tlestruc get_line(uint16_t index, vector< tlestruc > lines)
Get TLE from array of TLE&#39;s.
Definition: convertlib.cpp:3512
locstruc loc
Location structure.
Definition: jsondef.h:3596
int32_t att_geoc2icrf(locstruc *loc)
Definition: convertlib.cpp:1639
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
rvector rv_unitz(double scale)
Scaled z row vector.
Definition: vector.cpp:140
rvector rv_zero()
Zero row order vector.
Definition: vector.cpp:107
static stkstruc stkhandle
Definition: physicslib.cpp:45
int32_t load_lines(string fname, vector< tlestruc > &lines)
Load TLE from file. TODO!!! Rename Function to loadTle and create new class for dealing with TLEs...
Definition: convertlib.cpp:3612
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
uint32_t pass
pass indicator: allows synchronization with other attitude and position values.
Definition: convertdef.h:485
qatt topo
Definition: convertdef.h:826
void hardware_init_eci(cosmosstruc *cinfo, locstruc &loc)
Initialize Hardware.
Definition: physicslib.cpp:877
const double D2PI
Double precision 2*PI.
Definition: math/constants.h:16
quaternion s
0th derivative: Quaternion
Definition: convertdef.h:479
int32_t att_icrf2lvlh(locstruc *loc)
Definition: convertlib.cpp:1822
vector< piecestruc > pieces
Vector of all pieces in node.
Definition: jsondef.h:4232
double dt
Time step in seconds.
Definition: jsondef.h:3414
cartpos eci
Definition: convertdef.h:737
quaternion q_eye()
Identity quaternion.
Definition: vector.cpp:1310
int32_t mode
Definition: jsondef.h:3436
cartpos icrf
Definition: convertdef.h:736
double utc
Simulated starting time in MJD.
Definition: jsondef.h:3418
int32_t att_topo(locstruc *loc)
Definition: convertlib.cpp:2252
double utc
Definition: convertdef.h:923
int lines2eci(double utc, vector< tlestruc >lines, cartpos &eci)
Return position from TLE set.
Definition: convertlib.cpp:3155
double dtj
Time step in Julian days.
Definition: jsondef.h:3416
int32_t load_stk(string filename, stkstruc &stkdata)
Load STK elements.
Definition: convertlib.cpp:3792
physicsstruc phys
Definition: jsondef.h:3597
int stk2eci(double utc, stkstruc &stk, cartpos &eci)
ECI from STK data.
Definition: convertlib.cpp:3842