не понимаю, что от меня хочет компилятор

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

Здравствуйте. Скачал программу с++ и хочу заставить ее работать на arduino. Но компилятор на что то ругатеся. Привожу весь код в прикрепленном файле

вот, что говорит компилятор

sun.ino: In function 'double get_lon(double)':
sun.ino:490:1: error: unable to find a register to spill in class 'POINTER_REGS'
sun.ino:490:1: error: this is the insn:
(insn 301 300 304 5 (set (reg:SF 124 [ D.4715 ])
        (mem:SF (post_inc:HI (reg:HI 16 r16 [orig:149 ivtmp.78 ] [149])) [2 MEM[base: _224, offset: 0B]+0 S4 A8])) sun.ino:478 99 {*movsf}
     (expr_list:REG_INC (reg:HI 16 r16 [orig:149 ivtmp.78 ] [149])
        (nil)))
sun.ino:490: confused by earlier errors, bailing out
Ошибка компиляции.

Заранее спасибо!

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Наверное компилятор просит исправить ошибку в 490 строке.
Да, КЭП это я

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

В для капитана приведу строку 490

}

Я понимаю, что он ругается на саму процедуру, но не хватает знаний понять, что в ней не так.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Может кому то будет не лень посмотреть, а я с телефона считать 490 строку не буду, точно собьюсь. Вообще, обычно вставляют исходник с нумерацией строк и под спойлер, тогда и считать не нужно и посмотреть можно и без компа. Может посмотрю позже.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Arduino какая? Здесь сплошные double. Только массивы в начале занимают 1860 байт. На mega2560 (8К памяти) еще куда ни шло, но на UNO (2K) - можно смело сказать, что оно не будет работать, даже если скомпилируется.

Компилятор не может прожевать следующие конструкции:

    vl +=  *(AcrS + i + 49) * cos((*(sk2 + i * 4 + 0)) * l +
                                  (*(sk2 + i * 4 + 1)) * l1 +
                                  (*(sk2 + i * 4 + 2)) * F +
                                  (*(sk2 + i * 4 + 3)) * D);

При разбивке такой конструкции на следующую, компилятор прожевывает:

    double l_angle = (*(sk2 + i * 4 + 0)) * l;
    l_angle += (*(sk2 + i * 4 + 1)) * l1;
    l_angle += (*(sk2 + i * 4 + 2)) * F;
    l_angle += (*(sk2 + i * 4 + 3)) * D;
    vl +=  *(AcrS + i + 49) * cos(l_angle);

Таких фрагментов несколько, ищите и заменяйте.

Но если у Вас не mega2560, то в чистом виде скетч работать не будет.

PS Надеюсь, что пустые setup & loop - это пока еще не дописаное, потому что в таком виде скетч работать не будет вообще, даже если скомпилируется.

Я изменил setup & loop на:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(57600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(get_lon(15.78));
}

Поличились следующие данные по памяти:

Sketch uses 14,194 bytes (5%) of program storage space. Maximum is 253,952 bytes.
Global variables use 2,056 bytes (25%) of dynamic memory, leaving 6,136 bytes for local variables. Maximum is 8,192 bytes.

Это подтверждение моим словам. Компилировал для Mega2560. ArduinoIDE v1.6.3.

 

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

kisoft пишет:
Компилировал для Mega2560. ArduinoIDE v1.6.3.
огромное спасибо! буду править, на другом форуме по С++ мне помогли с "пониманием" что *(sk1 + n) тоже самое, что и sk1[n] :-) будет все это на меге работать, да и то, хочу этот массив в процедуру запихнуть, что бы раз в сутки это запускать в момент, когда память будет свободной от других данных. мне то только одно "число" нужно

кстати, подскажите, как мне убрать в процедуру этот массив, что бы раз в сутки его в память загонять, м.б. его на флешке хранить?

банально попробовал в "главную процедуру" перенести инициализацию переменных - начал ругаться на их отсуствие в других процедурах. их туда стоит "передавать" ?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Да, забить его во флеш, поскольку он не меняется. Считать будет медленней,но если это не критично, то пофиг.
На счёт "передавать" все равно его где то надо хранить, создавать динамически не думаю, что будет лучше.
На счёт *(sk1+n) и sk1[n] это одно и тоже и можно не менять, код будет тот же.
2k для меги2560 не напряжно, можно не париться.

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

я немного переработал код с целью сократить используемую память, исключил глобальные переменные. 

код не мой, поэтому комментарии сохранены

теперь его можно вклинивать в программу, пользуйтесь последней функцией, предварительно расчистив память, и не мучайтесь :-) как я 

/*********************************************************
 * sun.cpp
 * Функции для определения восхода и захода солнца
 * автор: Лысиков Александр 
 * e-mail: support@lavresearch.com
 * www: http://lavresearch.com
 * последние изменения: 31 марта 2005 г.
 *********************************************************/

//#include <time.h>
#include <math.h>

#define	PI (3.1415926535897932384626433832795)
#define C_T 36525.0

//процедура рассматривает любое время на конкретную дату 
struct tm {
  int tm_sec=0;     // seconds after the minute - [0,59] 
  int tm_min=0;     // minutes after the hour - [0,59] 
  int tm_hour=1;    // hours since midnight - [0,23] 
  int tm_mday;    // day of the month - [1,31] 
  int tm_mon;     // months since January - [0,11] 
  int tm_year;    // years since 1900 
  int tm_wday=0;    // days since Sunday - [0,6] 
  int tm_yday=0;    // days since January 1 - [0,365] 
  int tm_isdst=0;   // daylight savings time flag 
};


void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}


/**************************************************
 *	Перевод эфемеридной даты в Юлианское время
 * от 2000 года 1го числа 12 часов
 * return: число юлианских дней (от начала 2000г.)
 **************************************************/
double getJG(struct tm *newtime) {
  double km = 12*(newtime->tm_year+1900+4800)+newtime->tm_mon-2;// в годах
  double vj = (2*(km-12*floor(km/12))+7+365*km)/12;
  vj = floor(vj)+newtime->tm_mday+floor(km/48)-32083;
  if (vj>2299171) vj += floor(km/4800)-floor(km/1200)+38;
  vj += -2451545+
  (newtime->tm_hour/24.)+
  (newtime->tm_min/(24.*60))+
  (newtime->tm_sec/(24*3600.))-0.5;
  return vj;
}

/*********************************************************
 * Истинный наклон эклиптики к экватору земли
 * без учета нутации         в градусах 
 *********************************************************/
double  getE(double T) {
  double ret;
  double T1 = T/C_T;
  ret = (84381.448-46.8150*T1-0.00059*T1*T1+0.008813*T1*T1*T1)/3600.0;
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 * Средняя аномалия Луны в градусах 
 * эпоха J2000
 *********************************************************/
double retlJ(double T) {
  double ret;
  double T1 = T/C_T;
  ret = 485866.733+ (1325*1296000+715922.633)*T1+31.310*T1*T1+0.064*T1*T1*T1;
  ret /= 3600;//перевод в градусы
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 * Средняя аномалия Cолнца в градусах 
 * эпоха J2000
 *********************************************************/
double retl1J(double T) {
  double ret;
  double T1 = T/C_T;
  ret = 1287099.804+ (99*1296000+1292581.224)*T1-0.577*T1*T1-0.012*T1*T1*T1;
  ret /= 3600;//перевод в градусы
  ret = fmod (ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 **Венера** - Средняя долгота в градусах 
 * эпоха J2000
 *********************************************************/
double retl_Wn(double T) {
  double ret;
  double T1 = T/C_T;
  ret =181*3600+58*60+47.283+210669166.909*T1+1.1182*T1*T1+0.0001*T1*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 **Венера** - Средняя долгота перигея в градусах 
 * эпоха J2000
 *********************************************************/
double retp_Wn(double T) {
  double ret;
  double T1 = T/C_T;
  ret =131*3600+33*60+49.346+5047.994*T1-3.8618*T1*T1-0.0189*T1*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 **Марс** - Средняя долгота в градусах 
 * эпоха J2000
 *********************************************************/
double retl_Mar(double T) {
  double ret;
  double T1 = T/C_T;
  ret =355*3600+25*60+59.789+68910107.309*T1+1.1195*T1*T1+0.0001*T1*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 **Марс** - Средняя долгота перигея в градусах 
 * эпоха J2000
 *********************************************************/
double retp_Mar(double T) {
  double ret;
  double T1 = T/C_T;
  ret =336*3600+3*60+36.842+6627.759*T1+0.4864*T1*T1+0.0010*T1*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 **Юпитер** - Средняя долгота в градусах 
 * эпоха J2000
 *********************************************************/
double retl_Jup(double T) {
  double ret;
  double T1 = T/C_T;
  ret =34*3600+21*60+5.342+10930690.040*T1+0.8055*T1*T1+0.0001*T1*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 **Юпитер** - Средняя долгота перигея в градусах
 * эпоха J2000
 *********************************************************/
double retp_Jup(double T) {
  double ret;
  double T1 = T/C_T;
  ret =14*3600+19*60+52.713+5805.497*T1+3.7132*T1*T1-0.0159*T1*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}


/*********************************************************
 **Сатурн** - Средняя долгота в градусах
 * эпоха J2000
 *********************************************************/
double retl_Sat(double T) {
  double ret;
  double T1 = T/C_T;
  ret =50*3600+4*60+38.897+4404639.651*T1+1.8703*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 **Сатурн** - Средняя долгота перигея в градусах
 * эпоха J2000
 *********************************************************/
double retp_Sat(double T) {
  double ret;
  double T1 = T/C_T;
  ret =93*3600+3*60+24.434+7069.538*T1+3.0150*T1*T1+0.0181*T1*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 * Средний аргумент широты Луны, в градусах
 * эпоха J2000
 *********************************************************/
double retFJ(double T) {
  double ret;
  double T1 = T/C_T;
  ret = 335778.877+ (1342*1296000+295263.137)*T1-13.257*T1*T1+0.011*T1*T1*T1;
  ret /= 3600;//перевод в градусы
  ret = fmod (ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 * Разность средних долгот Луны и Солнца (Элонгация)в градусах
 * эпоха J2000
 *********************************************************/
double retDJ(double T) {
  double ret;
  double T1 = T/C_T;
  ret = 1072261.307+ (1236*1296000+1105601.328)*T1-6.891*T1*T1+0.019*T1*T1*T1;
  ret /= 3600;//перевод в градусы
  ret = fmod (ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 * Средняя долгота солнца - в градусах
 * эпоха J2000
 *********************************************************/
double retl_Sl(double T) {
  double ret;
  double T1 = T/C_T;
  ret =1009667.850+(129600000+2771.270)*T1+1.089*T1*T1;
  ret/=3600;// перевод в градусы из секунд
  ret = fmod(ret,360.0);
  if (ret<0) ret += 360.0;
  return ret;
}

/*********************************************************
 * Получение долготы Солнца 
 * (в градусах) (ошибка до +(2-8) секунд) 
 * t - Юлианское время от J2000
 *********************************************************/
double get_lon(double t) {
  double T = t/C_T;
  double ret=0, vl=0, lgr=0;
  double tmp;
  double l, l1, D, F, g1, g3, g4, g5;
  int i;
  double Tt;
  // Амплитуды для определения коэффициента SK для Солнца
  double AskS[53];
  // Амплитуды для определения коэффициента CK для Солнца
  double AckS[49];
  // Коэффициенты для определения положения Солнца
  // Учёт собственных возмущений
  byte sk1[245] = {//4*5  // всего 49*5
					 0, 0, 0, 0, 0,
					 1, 0, 0, 0, 0,
					 2, 0, 0, 0, 0,
					 3, 0, 0, 0, 0,

  // Учёт возмущений от Венеры //15*5
					 0, 1, 0, 0, 0,
					 1,-1, 0, 0, 0,
					 1,-2, 0, 0, 0,
					 2,-2, 0, 0, 0,
					 3,-2, 0, 0, 0,
					 3,-3, 0, 0, 0,
					 4,-3, 0, 0, 0,
					 5,-3, 0, 0, 0,
					 4,-4, 0, 0, 0,
					 5,-4, 0, 0, 0,
					 6,-4, 0, 0, 0,
					 5,-5, 0, 0, 0,
					 6,-6, 0, 0, 0,
					 7,-5, 0, 0, 0,
					 8,-5, 0, 0, 0,
  // Учёт возмущений от Марса //10*5
					 1, 0,-1, 0, 0,
					 2, 0,-2, 0, 0,
					 1, 0,-2, 0, 0,
					 2, 0,-3, 0, 0,
					 2, 0,-4, 0, 0,
					 3, 0,-4, 0, 0,
					 3, 0,-5, 0, 0,
					 3, 0,-3, 0, 0,
					 4, 0,-3, 0, 0,
					 4, 0,-5, 0, 0,
  // Учёт возмущений от Юпитера //12*5
					 0, 0, 0, 1, 0,
					 1, 0, 0,-3, 0,
					 1, 0, 0,-2, 0,
					 1, 0, 0,-1, 0,
					 1, 0, 0, 1, 0,
					 2, 0, 0,-4, 0,
					 2, 0, 0,-3, 0,
					 2, 0, 0,-2, 0,
					 2, 0, 0,-1, 0,
					 3, 0, 0,-4, 0,
					 3, 0, 0,-3, 0,
					 3, 0, 0,-2, 0,
  // Учёт возмущений от Сатурна //4*5
					 0, 0, 0, 0, 1,
					 1, 0, 0, 0,-2,
					 1, 0, 0, 0,-1,
					 2, 0, 0, 0,-2,
  // Учёт смешанных возмущений //4*5
					 0, 0, 0, 0, 1,
					 1, 0, 0, 0,-2,
					 1, 0, 0, 0,-1,
					 2, 0, 0, 0,-2};
  // Учёт возмущений от Луны
  byte sk2[16] = {//4*4
					 0, 0, 0, 1,
					 1, 0, 0, 1,
					 1, 0, 0,-1,
					 0, 1, 0,-1};
  // Средняя аномалия Луны
  l = retlJ(t);
  // Средняя аномалия Cолнца
  l1= retl1J(t);
  // Средняя аномалия Венеры
  g1= retl_Wn(t)-retp_Wn(t);
  // Средняя аномалия Марса
  g3= retl_Mar(t)-retp_Mar(t);
  // Средняя аномалия Юпитера
  g4= retl_Jup(t)-retp_Jup(t);
  // Средняя аномалия Сатурна
  g5= retl_Sat(t)-retp_Sat(t);
  l  *= PI/180.0;
  l1 *= PI/180.0;
  g1 *= PI/180.0;
  g3 *= PI/180.0;
  g4 *= PI/180.0;
  g5 *= PI/180.0;

  Tt = (t+36525)/C_T;//+ перевод во время от эпохи 1900 г.
  AskS[0] = 0;                                    AckS[0] = 0;            
  AskS[1] = 33502e-6-83.58e-6*Tt-0.25e-6*Tt*Tt;	  AckS[1] = 0;
  AskS[2] = 351e-6-1.75e-6*Tt;			  AckS[2] = 0;
  AskS[3] = 5e-6;				  AckS[3] = 0;
  AskS[4] = 0;		                          AckS[4] = 0;	
  AskS[5] =-20e-6;                                AckS[5] = 11e-6;
  AskS[6] = 0;		                          AckS[6] = 0;	
  AskS[7] = 14e-6;	                          AckS[7] =-23e-6;
  AskS[8] =-8e-6;		                  AckS[7] = 9e-6;	
  AskS[9] = 0;		                          AckS[8] =-3e-6;	
  AskS[10] =-2e-6;	                          AckS[10] = 7e-6;
  AskS[11] =-3e-6;	                          AckS[11] = 4e-6;	
  AskS[12] = 0;		                          AckS[12] =-1e-6;	
  AskS[13] = 0;		                          AckS[13] = 0;		
  AskS[14] = 0;		                          AckS[14] = 1e-6;	
  AskS[15] = 0;		                          AckS[15] = 0;		
  AskS[16] = 0;		                          AckS[16] = 0;		
  AskS[17] = 0;		                          AckS[17] = 0;		
  AskS[18] = 0;		                          AckS[18] = 1e-6;	
  AskS[19] = 1e-6;	                          AckS[19] =-1e-6;	
  AskS[20] = 3e-6;	                          AckS[20] = 10e-6;	
  AskS[21] = 3e-6;	                          AckS[21] =-8e-6;	
  AskS[22] = 1e-6;	                          AckS[22] = 2e-6;	
  AskS[23] = 1e-6;	                          AckS[23] = 3e-6;	
  AskS[24] =-2e-6;	                          AckS[24] = 0;		
  AskS[25] =-1e-6;	                          AckS[25] = 0;		
  AskS[26] = 0;		                          AckS[26] = 0;		
  AskS[27] = 0;		                          AckS[27] = 0;		
  AskS[28] = 0;		                          AckS[28] = 0;		
  AskS[29] =-13e-6;	                          AckS[29] =-1e-6;	
  AskS[30] =-1e-6;	                          AckS[30] = 0;		
  AskS[31] =-7e-6;	                          AckS[31] =-3e-6;	
  AskS[32] = 0;		                          AckS[32] =-35e-6;	
  AskS[33] = 0;		                          AckS[33] = 0;		
  AskS[34] = 0;		                          AckS[34] = 0;	
  AskS[35] =-3e-6;	                          AckS[35] = 0;		
  AskS[36] =-13e-6;	                          AckS[36] = 0;		
  AskS[37] = 0;		                          AckS[37] =-1e-6;	
  AskS[38] = 0;		                          AckS[38] = 0;		
  AskS[39] = 0;		                          AckS[39] =-1e-6;	
  AskS[40] = 0;		                          AckS[40] = 0;		
  AskS[41] =-2e-6;	                          AckS[41] = 0;		
  AskS[42] = 0;		                          AckS[42] = 0;		
  AskS[43] =-2e-6;	                          AckS[43] = 0;		
  AskS[44] = 0;		                          AckS[44] = 0;		
  AskS[45] = 0;		                          AckS[45] = 0;		
  AskS[46] = 25e-6;	                          AckS[46] = 18e-6;
  AskS[47] = 0;		                          AckS[47] = 0;		
  AskS[48] = 0;		                          AckS[48] =-1e-6;	
  // возмущения от луны
  AskS[49] = 31e-6;										
  AskS[50] = 1e-6;											
  AskS[51] = 2e-6;											
  AskS[52] =-1e-6;											

  for (i=0;i<49;i++) {
    tmp=(*(sk1+i*5+0))*l1;
    tmp+=(*(sk1+i*5+1))*g1;
    tmp+=(*(sk1+i*5+2))*g3;
    tmp+=(*(sk1+i*5+3))*g4;
    tmp+=(*(sk1+i*5+4))*g5;
    vl+=(*(AskS+i))*sin(tmp);
    tmp=(*(sk1+i*5+0))*l1;
    tmp+=(*(sk1+i*5+1))*g1;
    tmp+=(*(sk1+i*5+2))*g3;
    tmp+=(*(sk1+i*5+3))*g4;
    tmp+=(*(sk1+i*5+4))*g5;
    vl+=(*(AckS+i))*cos(tmp);
  }
  double a = 13*l1-8*g1+3.8990655+0.0785398*(t+36525)/C_T;
  vl += 6e-6*cos(a)+7e-6*sin(a);
  // Средний аргумент широты Луны
  F = retFJ(t);
  // Разность средних долгот Луны и Солнца
  D = retDJ(t);
  F *= PI/180.0;
  D *= PI/180.0;
  for (i=0;i<4;i++) {
    tmp=(*(sk2+i*4+0))*l;
    tmp+=(*(sk2+i*4+1))*l1;
    tmp+=(*(sk2+i*4+2))*F;
    tmp+=(*(sk2+i*4+3))*D;
    vl+=(*(AskS+i+49))*sin(tmp);
  }
  ret = retl_Sl(t);// средняя долгота солнца
  vl *= 180/PI;
  ret+= vl;
  ret = fmod(ret,360);
  if (ret<0)	ret+=360;
  return ret;

}

/*********************************************************
 * Получение Радиус-вектора солнца в средних расстояниях от
 * земли до солнца (до 5 знака после запятой)
 * (в астрономических еденицах)
 * t - Юлианское время от J2000
 *********************************************************/
double get_ri(double t) {
  double T = t/C_T;
  double ret=0, vl=0, lgr=0;
  double tmp;
  double l, l1, D, F, g1, g3, g4, g5;
  int i;
  double	Tt;
  // Амплитуды для определения коэффициента SR для Солнца
  double AsrS[49];
  // Амплитуды для определения коэффициента CR для Солнца
  double AcrS[53];

  // Коэффициенты для определения положения Солнца
  // Учёт собственных возмущений
  byte sk1[245] = {//4*5  // всего 49*5
					 0, 0, 0, 0, 0,
					 1, 0, 0, 0, 0,
					 2, 0, 0, 0, 0,
					 3, 0, 0, 0, 0,

  // Учёт возмущений от Венеры //15*5
					 0, 1, 0, 0, 0,
					 1,-1, 0, 0, 0,
					 1,-2, 0, 0, 0,
					 2,-2, 0, 0, 0,
					 3,-2, 0, 0, 0,
					 3,-3, 0, 0, 0,
					 4,-3, 0, 0, 0,
					 5,-3, 0, 0, 0,
					 4,-4, 0, 0, 0,
					 5,-4, 0, 0, 0,
					 6,-4, 0, 0, 0,
					 5,-5, 0, 0, 0,
					 6,-6, 0, 0, 0,
					 7,-5, 0, 0, 0,
					 8,-5, 0, 0, 0,
  // Учёт возмущений от Марса //10*5
					 1, 0,-1, 0, 0,
					 2, 0,-2, 0, 0,
					 1, 0,-2, 0, 0,
					 2, 0,-3, 0, 0,
					 2, 0,-4, 0, 0,
					 3, 0,-4, 0, 0,
					 3, 0,-5, 0, 0,
					 3, 0,-3, 0, 0,
					 4, 0,-3, 0, 0,
					 4, 0,-5, 0, 0,
  // Учёт возмущений от Юпитера //12*5
					 0, 0, 0, 1, 0,
					 1, 0, 0,-3, 0,
					 1, 0, 0,-2, 0,
					 1, 0, 0,-1, 0,
					 1, 0, 0, 1, 0,
					 2, 0, 0,-4, 0,
					 2, 0, 0,-3, 0,
					 2, 0, 0,-2, 0,
					 2, 0, 0,-1, 0,
					 3, 0, 0,-4, 0,
					 3, 0, 0,-3, 0,
					 3, 0, 0,-2, 0,
  // Учёт возмущений от Сатурна //4*5
					 0, 0, 0, 0, 1,
					 1, 0, 0, 0,-2,
					 1, 0, 0, 0,-1,
					 2, 0, 0, 0,-2,
  // Учёт смешанных возмущений //4*5
					 0, 0, 0, 0, 1,
					 1, 0, 0, 0,-2,
					 1, 0, 0, 0,-1,
					 2, 0, 0, 0,-2};
  // Учёт возмущений от Луны
  byte sk2[16] = {//4*4
					 0, 0, 0, 1,
					 1, 0, 0, 1,
					 1, 0, 0,-1,
					 0, 1, 0,-1};


  // Средняя аномалия Луны
  l = retlJ(t);
  // Средняя аномалия Cолнца
  l1= retl1J(t);
  // Средняя аномалия Венеры
  g1= retl_Wn(t)-retp_Wn(t);
  // Средняя аномалия Марса
  g3= retl_Mar(t)-retp_Mar(t);
  // Средняя аномалия Юпитера
  g4= retl_Jup(t)-retp_Jup(t);
  // Средняя аномалия Сатурна
  g5= retl_Sat(t)-retp_Sat(t);
  l  *= PI/180.0;
  l1 *= PI/180.0;
  g1 *= PI/180.0;
  g3 *= PI/180.0;
  g4 *= PI/180.0;
  g5 *= PI/180.0;

  Tt = (t+36525)/C_T;//+ перевод во время от эпохи 1900 г.
  AcrS[0] = 30570e-9-150e-9*Tt;	                AsrS[0] = 0;
  AcrS[1] =-7274120e-9+18140e-9*Tt+5e-9*Tt*Tt;	AsrS[1] = 0;
  AcrS[2] =-91380e-9+460e-9*Tt;			AsrS[2] =0;
  AcrS[3] =-1450e-9+10e-9*Tt;			AsrS[3] =0;
  AsrS[4] = 0;		                        AcrS[4] = 85e-9;
  AsrS[5] =-1146e-9;	                        AcrS[5] =-2062e-9;
  AsrS[6] = 136e-9;	                        AcrS[6] = 84e-9;
  AsrS[7] = 5822e-9;	                        AcrS[7] = 3593e-9;
  AsrS[8] =-632e-9;	                        AcrS[8] =-596e-9;
  AsrS[9] = 1044e-9;	                        AcrS[9] = 0;
  AsrS[10] =-1448e-9;	                        AcrS[10] =-381e-9;
  AsrS[11] = 148e-9;	                        AcrS[11] = 126e-9;
  AsrS[12] = 337e-9;	                        AcrS[12] =-166e-9;
  AsrS[13] = 189e-9;	                        AcrS[13] = 0;
  AsrS[14] =-91e-9;	                        AcrS[14] = 0;
  AsrS[15] = 93e-9;	                        AcrS[15] =-134e-9;
  AsrS[16] = 0e-9;	                        AcrS[16] =-80e-9;
  AsrS[17] = 136e-9;                       	AcrS[17] = 0;
  AsrS[18] = 0;		                        AcrS[18] = 0;
  AsrS[19] =-119e-9;                       	AcrS[19] =-92e-9;
  AsrS[20] = 1976e-9;                       	AcrS[20] =-573e-9;
  AsrS[21] = 137e-9;	                        AcrS[21] = 0;
  AsrS[22] = 201e-9;	                        AcrS[22] =-77e-9;
  AsrS[23] =-96e-9;	                        AcrS[23] = 0;
  AsrS[24] =-125e-9;	                        AcrS[24] = 461e-9;
  AsrS[25] = 0;		                        AcrS[25] = 87e-9;
  AsrS[26] = 0;		                        AcrS[26] =-154e-9;
  AsrS[27] =-94e-9;	                        AcrS[27] =-102e-9;
  AsrS[28] = 0;		                        AcrS[28] = 87e-9;
  AsrS[29] =-89e-9;	                        AcrS[29] = 227e-9;
  AsrS[30] = 0;		                        AcrS[30] = 172e-9;
  AsrS[31] =-486e-9;	                        AcrS[31] = 1376e-9;
  AsrS[32] =-7067e-9;                       	AcrS[32] = 0;
  AsrS[33] = 0;		                        AcrS[33] = 79e-9;
  AsrS[34] = 0;		                        AcrS[34] = 110e-9;
  AsrS[35] = 104e-9;	                        AcrS[35] = 796e-9;
  AsrS[36] = 203e-9;	                        AcrS[36] = 4021e-9;
  AsrS[37] =-193e-9;	                        AcrS[37] =-78e-9;
  AsrS[38] =-73e-9;	                        AcrS[38] = 0;
  AsrS[39] =-278e-9;	                        AcrS[39] = 0;
  AsrS[40] = 0;		                        AcrS[40] = 102e-9;
  AsrS[41] = 0;		                        AcrS[41] = 0;
  AsrS[42] = 0;		                        AcrS[42] =-103e-9;
  AsrS[43] =-79e-9;	                        AcrS[43] = 422e-9;
  AsrS[44] = 0;		                        AcrS[44] =-152e-9;
  AsrS[45] = 0;		                        AcrS[45] = 91e-9;
  AsrS[46] = 0;		                        AcrS[46] = 0;
  AsrS[47] = 0;		                        AcrS[47] =-91e-9;
  AsrS[48] = 0;		                        AcrS[48] = 0;
	// возмущения от луны
	                                        AcrS[49] = 13360e-9;
	                                        AcrS[50] = 0;
	                                        AcrS[51] =-1330e-9;
	                                        AcrS[52] = 0;


  for (i=0;i<49;i++) {
    tmp=(*(sk1+i*5+0))*l1;
    tmp+=(*(sk1+i*5+1))*g1;
    tmp+=(*(sk1+i*5+2))*g3;
    tmp+=(*(sk1+i*5+3))*g4;
    tmp+=(*(sk1+i*5+4))*g5;
    vl+=(*(AcrS+i))*sin(tmp);
    tmp=(*(sk1+i*5+0))*l1;
    tmp+=(*(sk1+i*5+1))*g1;
    tmp+=(*(sk1+i*5+2))*g3;
    tmp+=(*(sk1+i*5+3))*g4;
    tmp+=(*(sk1+i*5+4))*g5;
    vl+=(*(AcrS+i))*cos(tmp);
  }
  // Средний аргумент широты Луны
  F = retFJ(t);
  // Разность средних долгот Луны и Солнца
  D = retDJ(t);
  F *= PI/180.0;
  D *= PI/180.0;
  for (i=0;i<4;i++)
  {
    tmp=(*(sk2+i*4+0))*l;
    tmp+=(*(sk2+i*4+1))*l1;
    tmp+=(*(sk2+i*4+2))*F;
    tmp+=(*(sk2+i*4+3))*D;
    vl+=(*(AcrS+i+49))*cos(tmp);
  }
  //vl /= (3600);
  ret = ::pow((double)10.0,(double)vl);
  ret = pow((double)10.0,(double)vl);
  //if (ret<0)	ret+=360;
  return ret;
}

/**********************************************
 * Гривническое звездное время на
 * меридиане гринвича
 * вход:
 * t - Число Юлианских дней от J2000
 * выход: звездное время в часах
 **********************************************/

double star_time(double t) {
  double t0, // Число Юлианских дней до гривнической полуночи
	 so, // Гринвическое время от полуночи в часах
	 tmp,
	 M, M1; // Гринвическое время от полуночи в часах
	
  // Время от начала суток
  M1 = t-(int)t;
  if (M1>=0.5) {
    M = M1-0.5;
    t0 = (int)(t)+0.5;// Число Юлианских дней до гривнической полуночи
  }
  if (M1<0.5) {
    M = M1+0.5;
    t0 = (int)(t)-0.5;// Число Юлианских дней до гривнической полуночи
  }
  M *= 24;// перевод в часы;
  // Звездное время в гривническую полночь текущего дня
  tmp = t0/36525.0;//tmp = (t0-2415020.0)/36525.0;
  so = (21600+2460+50.54841+8640184.812866*tmp+0.093104*tmp*tmp-6.2*tmp*tmp*tmp);// в секундах
  // снова считаем число Юл. дней, но уже не от полуночи, а на тек. время
  tmp = t/36525.0;
  // добавим нутацию
  //double na1 = (cos(rete(tmp*36525.0)*PI/180.0)/15.0)*retDfJ(tmp*36525.0);
  //double na2 = (cos(rete(tmp*36525.0)*PI/180.0)/15.0)*retdfJ(tmp*36525.0);
  //so += (cos(rete(tmp*36525.0)*PI/180.0)/15.0)*retDfJ(tmp*36525.0);
  //so += (cos(rete(tmp*36525.0)*PI/180.0)/15.0)*retdfJ(tmp*36525.0);
  so /= 3600.0; // в часах
  so += M*1.0027379093;// плюс текущее время от гривнической полуночи
  so = fmod(so, 24.0);
  if (so<0) so+=24;
  return so;
}

/*********************************************************
 * Получение видимого прямого восхождения и склонения
 * по широте и долготе
 * La - широта - станет прямым восхождением - в градусах
 * Lo - долгота - станет склонением  - в градусах
 * //t - юлианское время J2000
 * e - угол поворота( наклон эклиптики) - в градусах
 *********************************************************/
void get_LaLo(double& La,double& Lo,double e) {
 double	z;
 double	f,// широта
	t,// часовой угол
	l,// склонение
	A;// 
	//a;// прям. восхождение

  f = 90-e;
  t = 90-Lo;
  l = La;
	
  f *= (PI/180.0);
  t *= (PI/180.0);
  l *= (PI/180.0);

  z = sin(f)*sin(l)+cos(f)*cos(l)*cos(t);
  //ASSERT(z>=-1 && z<=1);
  double z1 = acos(z);
  z1 = acos(z);// повтор, иначе не работает!!!
  z1 = z1*(180.0/PI);
  Lo = 90-z1;// склонение
  Lo = fmod(Lo,360);
  if (Lo<0) Lo += 360;

  A = atan2((cos(l)*sin(t)),(-sin(l)*cos(f)+cos(l)*sin(f)*cos(t)));
  A *= (180.0/PI);
  La = 90-A;
  La = fmod(La,360);
  if (La<0) La += 360;
}
// Структура, содержащая время, используются только первые 6 переменных
//struct tm {
//        int tm_sec;     // seconds after the minute - [0,59] 
//        int tm_min;     // minutes after the hour - [0,59] 
//        int tm_hour;    // hours since midnight - [0,23] 
//        int tm_mday;    // day of the month - [1,31] 
//        int tm_mon;     // months since January - [0,11] 
//        int tm_year;    // years since 1900 
//        int tm_wday;    // days since Sunday - [0,6] 
//        int tm_yday;    // days since January 1 - [0,365] 
//        int tm_isdst;   // daylight savings time flag 

// Вычисление восхода и захода солнца (везде время местное)
// вход:
// loc_time : локальное время (любое время текущего дня)
// time_zone : часовой сдвиг от гринвича (например для Москвы зимой=4, летом=5)
// f, l : широта и долгота местоположения (в градусах)
// выход:
// t_rise : указатель на число, которое будет содержать время восхода солнца (в часах)
// t_set  : указатель на число, которое будет содержать время захода солнца (в часах)
// возвращает: 
// 1 : все ОК
//-1 : сегодня не всходит (весь день темно или полярная ночь)
//-2 : сегодня не заходит (весь день светло или полярный день)

int sun_rise_set(struct tm *loc_time,double time_zone,double f, double l, double *t_rise,double *t_set) {
  
  double t0;// Юлианское время в гринвичскую полночь
  double t;// текущее Юлианское время
  double lat,lon;// широта, долгота солнца
  //double h,A;// высота, азимут
  double e;// наклон эклиптики к экватору
  double r;// нормированный радиус-вектор ~1
  double s1,s2;// звездное время восхода и захода
  double s0;//звездное время
  double z;//зенитное расстояние горизонта
  double dz;//добавка к зенитному расстоянию горизонта
  double cost;// значение косинуса (м.б. > 1!)
  double v = 1-0.0027304336;// для перевода из звездного в обычное время

  // переводим во время на середину дня
  loc_time->tm_hour = 12-(int)time_zone;
  loc_time->tm_min = 0;
  loc_time->tm_sec = 0;
  // определяем Юлианское время (на середину текущего дня)
  t = getJG(loc_time);

  // переводим во время на гринвческую полночь
  loc_time->tm_hour = 0;
  // определяем Юлианское время (на гринвческую полночь)
  t0 = getJG(loc_time);

  // Определяем положение солнца на эклиптике
  e = getE(t);// наклон эклиптики к экватору
  lon = get_lon(t);// долгота солнца - longitude
  lat = 0;// широта солнца - latitude
  r = get_ri(t);// нормированный радиус-вектор ~1
	
  //вычисляем добавку к зенитному расстоянию горизонта
  dz = 0;
  dz+= 34.5/60.;// рефракция=35'
  //dz+= d;// высота места
  dz+= (961.18/r)/3600.;// угловой радиус солнца ~ 16'
  dz-= (8.794/r)/3600.;// параллакс ~ 9"
  z = 90+dz;
	
  // поиск видимого прямого восхождения и склонения
  // lat: широта  -> прямое восхождение (в градусах)
  // lon: долгота -> склонение (в градусах)
  get_LaLo(lat,lon,e);
  lat/=15;// переводим прямое восхождение из градусов в часы
  
  //вычисляем местное звездное время
  s0 = star_time(t0)*15;
  s0 += l;//местное звездное время
  if (s0<0) s0+=360;
  s0 = fmod(s0,360)/15.;// перевод в часы
	
  // перевод в радианы
  lon *= (PI/180.0);
  z *= (PI/180.0);
  f *= (PI/180.0);
  cost = (cos(z)-sin(f)*sin(lon))/(cos(f)*cos(lon));
  if (cost>1)// солнце не всходит
    return -1;
  if (cost<-1)// солнце не заходит
    return -2;
  // смещения времени от истинного полудня
  double dt = acos(cost);
  dt *= (12./PI);// переводим в часы из радиан
  if (dt<0) dt+=24;
  if (dt<=12) {
    s1  = lat-dt;
    s2 = lat+dt;
  } else {
    s1  = lat+dt;
    s2 = lat-dt;
  }
  *t_rise  = (s1-s0)*v+time_zone;
  *t_set = (s2-s0)*v+time_zone;
  if ((*t_rise)<0) (*t_rise)+=24;
  if ((*t_set)<0) (*t_set)+=24;

  return 1;
}