static bit findVoidAsMatrix(BoardPieces* config,int* i,int* j) { for(*i=0;*i<boardRows;(*i)++) { for(*j=0;*j<boardColumns;(*j)++) { // printf("(%d,%d)\n",*i,*j); if(config[MIndex(*i, *j, boardRows)]==Void) return True; } } return False; }
void MPrint(Matrix A,int n) { int i,j; for(i=0;i<n;i++) { printf("| "); for(j=0;j<n;j++) { printf("%c ",A[MIndex(i,j,n)]); } printf("|\n"); } printf("\n"); }
static void SetParameters(enum multiCommand command, unsigned short *dataq, double* rvalues, int* ivalues, char svalues[][CMD_STRING_LEN]) { int i, dataqind; char type; int index = MIndex(command); char** dataqc = (char**) dataq; /* compute renormalised values - SIPSS FIFO version */ for (i = dataqind = 0; i < mcommands[index].numparams; ++i) { type = mcommands[index].params[i].type; if (type == 'i') /* 15 bit unsigned integer */ { ivalues[i] = atoi(dataqc[dataqind++]); bprintf(info, "Commands: param%02i: integer: %i\n", i, ivalues[i]); } else if (type == 'l') /* 30 bit unsigned integer */ { ivalues[i] = atoi(dataqc[dataqind++]); bprintf(info, "Commands: param%02i: long : %i\n", i, ivalues[i]); } else if (type == 'f') /* 15 bit floating point */ { rvalues[i] = atof(dataqc[dataqind++]); bprintf(info, "Commands: param%02i: float : %f\n", i, rvalues[i]); } else if (type == 'd') { /* 30 bit floating point */ rvalues[i] = atof(dataqc[dataqind++]); bprintf(info, "Commands: param%02i: double : %f\n", i, rvalues[i]); } else if (type == 's') { /* string */ strncpy(svalues[i], dataqc[dataqind++], CMD_STRING_LEN - 1); svalues[i][CMD_STRING_LEN - 1] = 0; bprintf(info, "Commands: param%02i: string: %s\n", i, svalues[i]); } else bprintf(err, "Commands: Unknown parameter type ('%c') param%02i: ignored", type, i); } bprintf(info, "Commands: Multiword Command: %d (%s)\n", command, MName(command)); }
static void LoadSchedFile(const char* file, struct ScheduleType* S, int lband) { FILE *fp; char line_in[MAX_LINE_LENGTH]; char *token[MAX_N_PARAMS + 4]; char *ptr; double hours; struct tm ts; double dt; double d_lon; int day, command, type; double check_lat = NOMINAL_LATITUDE + lband * (LATITUDE_BAND - LATITUDE_OVERLAP); double az1, az2, el1, el2, height; int i, j, k, entry_ok; int n_fields, mindex; int el_range_warning; int discarded_lines; blast_sched("********************************************\n" "*** Schedule: %s\n", file); /*******************************************/ /*** Count number of schedule file lines ***/ if ((fp = fopen(file, "r")) == NULL) { berror(err, "Scheduler: Unable to open schedule file %s", file); S->n_sched = 0; return; } while (GetLine(fp, line_in)) S->n_sched++; S->n_sched--; /* don't count date line */ if (S->n_sched > MAX_NSCHED) { berror(err, "Scheduler: schedule '%s' has too many commands", file); S->n_sched = MAX_NSCHED; } S->event = (struct ScheduleEvent*)balloc(fatal, S->n_sched * sizeof(struct ScheduleEvent)); blast_sched("*** Lines: %i\n", S->n_sched); if (fclose(fp) == EOF) berror(err, "Scheduler: Error on close"); /**************************/ /*** Read Starting Time ***/ if ((fp = fopen(file, "r")) == NULL) { berror(err, "Scheduler: Unable to open schedule file"); S->n_sched = 0; return; } GetLine(fp, line_in); strncpy(lst0str, line_in, 80); sscanf(line_in, "%d-%d-%d %d:%d:%d", &(ts.tm_year), &(ts.tm_mon), &(ts.tm_mday), &(ts.tm_hour), &(ts.tm_min), &(ts.tm_sec)); if (ts.tm_year < 50) ts.tm_year += 100; else ts.tm_year -= 1900; ts.tm_isdst = 0; ts.tm_mon--; /* Jan is 0 in struct tm.tm_mon, not 1 */ S->t0 = mktime(&ts) - timezone; /*************************************************************/ /** find local comoving siderial date (in siderial seconds) **/ //166 east lon dt = (mcp_systime(NULL) - S->t0) * 1.002737909; /* Ref Siderial Time */ d_lon = CHECK_LON; while (d_lon < 0) d_lon += 360.0; while (d_lon >= 360.0) d_lon -= 360.0; dt -= (d_lon * 3600.00 * 24.00 / 360.0); /* add longitude correction */ dt /= 3600.0; if (lband>-10) { blast_sched("*** Current LST (hours) %g\n" //relative to schedule epoch "*** For checks: LAT=%g, LON=%g\n", dt, check_lat, CHECK_LON); } /***********************/ /*** Read the events ***/ discarded_lines = 0; for (i = j = 0; i < S->n_sched; i++) { entry_ok = 1; GetLine(fp, line_in); /* Tokenise the string */ k = 0; n_fields = 1; ptr = line_in; token[0] = ptr; for (;;) { if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n' || *ptr == '\r') { if (k) *(ptr - 1) = '\0'; else k = 1; } else { if (k) { *(ptr - 1) = '\0'; token[n_fields++] = ptr; } k = 0; } if (*ptr == '\0' || *ptr == '#' || *ptr == '\n') break; ++ptr; } /* decrypt tag to find command */ command = MCommand(token[0]); if (command == -1) { S->event[j].is_multi = 0; command = SCommand(token[0]); if (command == -1) { blast_sched("Scheduler: *** ERROR: command not recognised: %s\n", token[0]); entry_ok = 0; } } else S->event[j].is_multi = 1; S->event[j].command = command; /* lst */ if (n_fields < 3) { blast_sched("Scheduler: *** ERROR: cannot find lst!\n"); entry_ok = 0; } else { day = atoi(token[1]); hours = atof(token[2]); S->event[j].t = day * 24l * 3600l + hours * 3600l; } /* Parameters */ if (entry_ok && S->event[j].is_multi) { mindex = MIndex(command); if (n_fields < 3 + mcommands[mindex].numparams) { blast_sched("Scheduler: *** ERROR: insufficient parameters for " "command (wanted %i; got %i)\n", mcommands[mindex].numparams, n_fields - 3); entry_ok = 0; } else for (k = 0; k < mcommands[mindex].numparams; ++k) { type = mcommands[mindex].params[k].type; if (type == 'i') /* 15 bit unsigned integer */ S->event[j].ivalues[k] = atoi(token[k + 3]); else if (type == 'l') /* 30 bit unsigned integer */ S->event[j].ivalues[k] = atoi(token[k + 3]); else if (type == 'f') /* 15 bit floating point */ S->event[j].rvalues[k] = atof(token[k + 3]); else if (type == 'd') /* 30 bit floating point */ S->event[j].rvalues[k] = atof(token[k + 3]); } } if (!entry_ok) { blast_sched( "Scheduler: ****** Warning Line %i is Malformed: Skipping *****\n", i); discarded_lines++; } else j++; } S->n_sched -= discarded_lines; if (lband>-10) { for (i = 0; i < S->n_sched; i++) { if (S->event[i].command == box || S->event[i].command == vbox || S->event[i].command == cap || S->event[i].command == vcap) { radec2azel(S->event[i].rvalues[0], S->event[i].rvalues[1], S->event[i].t, check_lat, &az1, &el1); if (i == S->n_sched - 1) radec2azel(S->event[i].rvalues[0], S->event[i].rvalues[1], S->event[i].t, check_lat, &az2, &el2); else radec2azel(S->event[i].rvalues[0], S->event[i].rvalues[1], S->event[i + 1].t, check_lat, &az2, &el2); height = S->event[i].rvalues[3]; if (S->event[i].command == box || S->event[i].command == vbox) height /= 2; el_range_warning = 0; if (el1 > el2) { el1 += height; el2 -= height; if (el1 > 60.0) el_range_warning = 1; if (el2 < 25.0) el_range_warning = 1; } else { el1 -= height; el2 += height; if (el2 > 60.0) el_range_warning = 1; if (el1 < 25.0) el_range_warning = 1; } if (el_range_warning && 0) { // FIXME: reenable blast_sched("Scheduler: ******************************************\n" "Scheduler: *** Warning: El Range of Event %i (%s)\n", i, CommandName(S->event[i].is_multi, S->event[i].command)); blast_sched("Scheduler: *** LST: %i/%7.4f Ra: %8.3f Dec: %8.3f\n", (int)(S->event[i].t / 86400), fmod(S->event[i].t / 3600.0, 24), S->event[i].rvalues[0], S->event[i].rvalues[1]); blast_sched("Scheduler: *** LST: %7.4f Az: %8.3f - %8.3f El: " "%8.3f - %8.3f\n", S->event[i].t / 3600.0, az1, az2, el1, el2); } } } bputs(sched, "********************************************\n"); } if (discarded_lines) blast_warn("Discarded %i malformed lines from schedule file.", discarded_lines); if (fclose(fp) == EOF) berror(err, "Scheduler: Error on close"); }
void DoSched(void) { time_t t; double dt; double d_lon; double d_lat; static int last_is = -1; static int last_s = -1; static int last_l = -1; static int last_slot = -1; static int last_up = -1; int i_sched, i_point; int i, index; struct ScheduleType *S = &_S[CommandData.sucks][CommandData.lat_range]; struct ScheduleEvent event; i_point = GETREADINDEX(point_index); d_lat = PointingData[i_point].lat - NOMINAL_LATITUDE; if (last_up != CommandData.uplink_sched) { last_up = CommandData.uplink_sched; last_is = -1; } // Check for invalid uplinked schedule file if (CommandData.uplink_sched) { if (Uplink_S == 0) { CommandData.uplink_sched = 0; } else if (Uplink_S->n_sched<2) { CommandData.uplink_sched = 0; } } if (CommandData.uplink_sched) { if (last_slot != CommandData.slot_sched) { last_slot = CommandData.slot_sched; last_is = -1; } S = Uplink_S; } else { /* check our latitude band */ if (CommandData.lat_range == 2) { /* southern band */ if (d_lat > -(LATITUDE_BAND / 2) + LATITUDE_OVERLAP) { blast_info("Scheduler: Entering middle latitude band. (%g)\n", d_lat); CommandData.lat_range = 1; } } else if (CommandData.lat_range == 1) { /* middle band */ if (d_lat < -(LATITUDE_BAND / 2)) { blast_info("Scheduler: Entering southern latitude band. (%g)\n", d_lat); CommandData.lat_range = 2; } else if (d_lat > (LATITUDE_BAND / 2)) { blast_info("Scheduler: Entering northern latitude band. (%g)\n", d_lat); CommandData.lat_range = 0; } } else if (CommandData.lat_range == 0) { /* norhtern band */ if (d_lat < (LATITUDE_BAND / 2) - LATITUDE_OVERLAP) { blast_info("Scheduler: Entering middle latitude band. (%g)\n", d_lat); CommandData.lat_range = 1; } } else { blast_warn("Scheduler: Unexpected latitude band: %i\n", CommandData.lat_range); CommandData.lat_range = 1; } S = &_S[CommandData.sucks][CommandData.lat_range]; /* check to see if we've changed schedule files */ if (last_l != CommandData.lat_range) { last_is = -1; last_l = CommandData.lat_range; } if (last_s != CommandData.sucks) { last_is = -1; last_s = CommandData.sucks; } } /* no schedule file case */ if (S->n_sched < 1) { doing_schedule = 0; return; } /*************************************************************/ /** find local comoving siderial date (in siderial seconds) **/ dt = (PointingData[i_point].t - S->t0) * 1.002737909; /*Ref Siderial Time */ d_lon = PointingData[i_point].lon; while (d_lon < -170) d_lon += 360.0; while (d_lon >= 190.0) d_lon -= 360.0; dt -= ((d_lon) * 3600.00 * 24.00 / 360.0); /* add longitude correction */ sched_lst = dt; t = PointingData[i_point].t; if (t < CommandData.pointing_mode.t) { doing_schedule = 0; last_is = -1; return; } if (PointingData[i_point].at_float && !CommandData.at_float) { bputs(info, "Scheduler: *** Executing initial float commands. ***\n"); /* el on */ event.command = el_on; event.is_multi = 0; ScheduledCommand(&event); /* unlock */ event.command = unlock; ScheduledCommand(&event); /* az on */ event.command = az_on; ScheduledCommand(&event); /* point antisolar */ event.command = antisun; ScheduledCommand(&event); /* enable hwpr autostepping */ event.command = hwpr_step_on; ScheduledCommand(&event); /* pot_valve_open */ event.command = pot_valve_open; ScheduledCommand(&event); event.command = pot_valve_on; ScheduledCommand(&event); /* turn off lock motor hold current */ event.command = lock_i; event.is_multi = 1; event.ivalues[0] = 50; event.ivalues[1] = 0; ScheduledCommand(&event); /* fridge autocylce system active */ event.command = auto_cycle; event.is_multi = 0; ScheduledCommand(&event); // out of sched mode for a while CommandData.pointing_mode.t = t + 30; doing_schedule = 0; /* Remember we're at float */ CommandData.at_float = 1; bputs(info, "Scheduler: *** Initial float commands complete. ***\n"); return; } /******************/ /** find i_sched **/ i_sched = last_is; if (i_sched < 0) i_sched = 0; while ((i_sched < S->n_sched - 1) && (dt > S->event[i_sched].t)) i_sched++; while ((i_sched > 0) && (dt < S->event[i_sched].t)) i_sched--; /******************************/ /** Execute initial controls **/ if (!doing_schedule) { bputs(info, "Scheduler: *** Entering schedule file mode. ***\n" "Scheduler: *** Running initial schedule controls. ***\n"); /* bias fixed */ event.command = fixed; event.is_multi = 0; //ScheduledCommand(&event); /* cal repeat */ event.command = cal_repeat; event.is_multi = 1; event.ivalues[0] = 130; /* ms */ event.ivalues[1] = 600; /* s */ //ScheduledCommand(&event); bputs(info, "Scheduler: *** Searching for current pointing mode. ***\n"); /* find last pointing command */ for (i = i_sched; i >= 0; --i) if (S->event[i].is_multi) { index = MIndex(S->event[i].command); if (mcommands[index].group & GR_POINT) break; } else { index = SIndex(S->event[i].command); if (scommands[index].group & GR_POINT) break; } if (i == -1) { bputs(warning, "Scheduler: *** No previous pointing mode, turning antisolar. ***\n"); event.command = antisun; event.is_multi = 0; ScheduledCommand(&event); } else if (i == i_sched) { bputs(info, "Scheduler: *** Pointing mode change imminent. ***\n"); } else { blast_info( "Scheduler: *** Recovering scheduled pointing mode (event %i). ***\n", i); ScheduledCommand(&S->event[i]); } } doing_schedule = 1; /*******************************/ /** Execute scheduled command **/ dt /= 3600; if (i_sched != last_is) { blast_info("Scheduler: Submitting event %i from %s to command " "subsystem (LST = %i/%f)", i_sched, filename[CommandData.sucks][CommandData.lat_range], (int)(dt / 24), fmod(dt, 24)); ScheduledCommand(&S->event[i_sched]); } last_is = i_sched; }
void WatchFIFO () { unsigned char buf[1]; char command[100]; char pbuf[30]; int fifo; int mcommand = -1; int mcommand_count = 0; char *mcommand_data[DATA_Q_SIZE]; int i; nameThread("SIPSS"); for (i = 0; i < DATA_Q_SIZE; ++i) { mcommand_data[i] = NULL; } double rvalues[MAX_N_PARAMS]; int ivalues[MAX_N_PARAMS]; char svalues[MAX_N_PARAMS][CMD_STRING_LEN]; int index, pindex = 0; bputs(startup, "WatchFIFO startup\n"); if ((fifo = open("/data/etc/SIPSS.FIFO", O_RDONLY | O_NONBLOCK)) == -1) berror(tfatal, "Unable to open FIFO"); for (;;) { index = 0; do { /* Loop until data come in */ while (read(fifo, buf, 1) <= 0) usleep(10000); /* sleep for 10ms */ command[index++] = buf[0]; } while (buf[0] != '\n'); command[index - 1] = command[index] = 0; bprintf(info, "Command received: %s\n", command); index = -1; while((command[++index] != ' ') && command[index]); command[index++] = 0; pindex = 0; mcommand_count = 0; do { if ((command[index] == ' ' || command[index] == 0) && pindex > 0) { pbuf[pindex] = 0; mcommand_data[mcommand_count] = reballoc(tfatal, mcommand_data[mcommand_count], pindex + 2); strncpy(mcommand_data[mcommand_count++], pbuf, pindex + 1); pindex = 0; } else { pbuf[pindex++] = command[index]; } } while (command[index++] != 0); bprintf(info, "%i parameters found.\n", mcommand_count); pthread_mutex_lock(&mutex); /* Process data */ if (mcommand_count == 0) { mcommand = SCommand(command); SingleCommand(mcommand, 0); mcommand = -1; } else { mcommand = MCommand(command); bputs(info, "Multi word command received\n"); if (mcommand_count == mcommands[MIndex(mcommand)].numparams) { SetParameters(mcommand, (unsigned short*)mcommand_data, rvalues, ivalues, svalues); MultiCommand(mcommand, rvalues, ivalues, svalues, 0); } else { bputs(warning, "Ignoring mal-formed command!\n"); } mcommand = -1; } /* Relinquish control of memory */ pthread_mutex_unlock(&mutex); } }
static const char* MName(enum multiCommand command) { int i = MIndex(command); return (i == -1) ? UnknownCommand : mcommands[i].name; }