int gpio_set_direction(int pin, int direction) { int ret = 0; int fd; char *str; char path[256]; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin); if ((fd = open(path, O_WRONLY)) < 0) { CATERR("Failed to open %s\n", path); return -1; } str = direction ? "in" : "out"; if (write(fd, str, strlen(str)) < 0) { CATERR("Failed to write \"%s\" to %s\n", str, path); //ret = -2; } close(fd); return ret; }
int catcierge_rfid_open(catcierge_rfid_t *rfid) { struct termios options; assert(rfid); if ((rfid->fd = open(rfid->serial_path, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) { CATERR("%s RFID Reader: Failed to open RFID serial port %s\n", rfid->name, rfid->serial_path); return -1; } CATLOG("%s RFID Reader: Opened serial port %s on fd %d\n", rfid->name, rfid->serial_path, rfid->fd); if (fcntl(rfid->fd, F_SETFL, 0) < 0) { close(rfid->fd); CATERR("%s RFID Reader: fcntl error %d while trying to open file descriptor, %s", rfid->name, errno, strerror(errno)); return -1; } memset(&options, 0, sizeof(options)); // Set baud rate. cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); options.c_iflag = 0; options.c_oflag = 0; // Raw output. options.c_cflag = CS8 | CREAD | CLOCAL; options.c_lflag = 0; options.c_cc[VTIME] = 0; options.c_cc[VMIN] = 1; // Flush the line and set the options. tcflush(rfid->fd, TCIFLUSH); tcsetattr(rfid->fd, TCSANOW, &options); // Set the reader in RAT mode. if (catcierge_rfid_write_rat(rfid)) { CATERR("%s RFID Reader: Failed to write RAT command\n", rfid->name); catcierge_rfid_destroy(rfid); return -1; } rfid->state = CAT_CONNECTED; return 0; }
int gpio_export(int pin) { if (write_num_to_file("/sys/class/gpio/export", pin)) { CATERR("Failed to open GPIO export for writing\n"); return -1; } return 0; }
void setup_sig_handlers() { if (signal(SIGINT, sig_handler) == SIG_ERR) { CATERR("Failed to set SIGINT handler\n"); } #ifndef _WIN32 if (signal(SIGUSR1, sig_handler) == SIG_ERR) { CATERR("Failed to set SIGUSR1 handler (used to force unlock)\n"); } if (signal(SIGUSR2, sig_handler) == SIG_ERR) { CATERR("Failed to set SIGUSR2 handler (used to force lockout)\n"); } #endif // _WIN32 }
int gpio_write(int pin, int val) { char path[256]; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); if (write_num_to_file(path, val)) { CATERR("Failed to open GPIO export for writing\n"); return -1; } return 0; }
char *catcierge_read_file(const char *filename) { char *buffer = NULL; int string_size; int read_size; FILE *f; if (!(f = fopen(filename,"r"))) { CATERR("Failed to open file %s\n", filename); return NULL; } fseek(f, 0, SEEK_END); string_size = ftell(f); rewind(f); if (!(buffer = (char *)malloc(sizeof(char) * (string_size + 1)))) { goto fail; } read_size = fread(buffer, sizeof(char), string_size, f); buffer[string_size] = '\0'; if (string_size != read_size) { CATERR("Failed to read file %s\n", filename); free(buffer); buffer = NULL; } fail: if (f) fclose(f); return buffer; }
static int write_num_to_file(const char *path, int num) { int ret = 0; char buf[16]; int fd; ssize_t written; if ((fd = open(path, O_WRONLY)) < 0) { CATERR("Failed to open \"%s\"\n", path); return -1; } written = snprintf(buf, sizeof(buf), "%d", num); if (write(fd, buf, strlen(buf)) < 0) { CATERR("Failed to write \"%s\" to %s\n", buf, path); } close(fd); return ret; }
int catcierge_rfid_write_rat(catcierge_rfid_t *rfid) { const char buf[] = "RAT\r\n"; ssize_t bytes = write(rfid->fd, buf, sizeof(buf)); CATLOG("%s RFID Reader: Sent RAT request\n", rfid->name); if (bytes < 0) { CATERR("%s RFID Reader: Failed to write %d, %s\n", rfid->name, errno, strerror(errno)); return -1; } return 0; }
int catcierge_parse_setting(catcierge_args_t *args, const char *key, char **values, size_t value_count) { size_t i; int ret; assert(args); assert(key); if (!strcmp(key, "matcher")) { if (value_count == 1) { args->matcher = values[0]; if (strcmp(args->matcher, "template") && strcmp(args->matcher, "haar")) { fprintf(stderr, "Invalid template type \"%s\"\n", args->matcher); return -1; } args->matcher_type = !strcmp(args->matcher, "template") ? MATCHER_TEMPLATE : MATCHER_HAAR; return 0; } else { fprintf(stderr, "Missing value for --matcher\n"); return -1; } return 0; } ret = catcierge_haar_matcher_parse_args(&args->haar, key, values, value_count); if (ret < 0) return -1; else if (!ret) return 0; ret = catcierge_template_matcher_parse_args(&args->templ, key, values, value_count); if (ret < 0) return -1; else if (!ret) return 0; if (!strcmp(key, "show")) { args->show = 1; if (value_count == 1) args->show = atoi(values[0]); return 0; } if (!strcmp(key, "ok_matches_needed")) { if (value_count == 1) { args->ok_matches_needed = atoi(values[0]); if ((args->ok_matches_needed < 0) || (args->ok_matches_needed > MATCH_MAX_COUNT)) { fprintf(stderr, "--ok_matches_needed must be between 0 and %d\n", MATCH_MAX_COUNT); return -1; } return 0; } fprintf(stderr, "--ok_matches_needed missing an integer value\n"); return -1; } if (!strcmp(key, "lockout_method")) { if (value_count == 1) { args->lockout_method = atoi(values[0]); if ((args->lockout_method < OBSTRUCT_OR_TIMER_1) || (args->lockout_method > TIMER_ONLY_3)) { fprintf(stderr, "--lockout_method needs a value between %d and %d\n", OBSTRUCT_OR_TIMER_1, TIMER_ONLY_3); return -1; } return 0; } fprintf(stderr, "--lockout_method missing an integer value\n"); return -1; } if (!strcmp(key, "save")) { args->saveimg = 1; if (value_count == 1) args->saveimg = atoi(values[0]); return 0; } if (!strcmp(key, "save_obstruct")) { args->save_obstruct_img = 1; if (value_count == 1) args->save_obstruct_img = atoi(values[0]); return 0; } if (!strcmp(key, "new_execute")) { args->new_execute = 1; if (value_count == 1) args->new_execute = atoi(values[0]); return 0; } if (!strcmp(key, "highlight")) { args->highlight_match = 1; if (value_count == 1) args->highlight_match = atoi(values[0]); return 0; } if (!strcmp(key, "lockout")) { args->lockout_time = DEFAULT_LOCKOUT_TIME; if (value_count == 1) args->lockout_time = atoi(values[0]); return 0; } if (!strcmp(key, "lockout_error_delay")) { if (value_count == 1) { args->consecutive_lockout_delay = atof(values[0]); return 0; } fprintf(stderr, "--lockout_error_delay missing a seconds value\n"); return -1; } if (!strcmp(key, "lockout_error")) { if (value_count == 1) { args->max_consecutive_lockout_count = atoi(values[0]); return 0; } fprintf(stderr, "--lockout_error missing a value\n"); return -1; } if (!strcmp(key, "lockout_dummy")) { args->lockout_dummy = 1; if (value_count == 1) args->lockout_dummy = atoi(values[0]); return 0; } if (!strcmp(key, "matchtime")) { args->match_time = DEFAULT_MATCH_WAIT; if (value_count == 1) args->match_time = atoi(values[0]); return 0; } if (!strcmp(key, "no_final_decision")) { args->no_final_decision = 1; if (value_count == 1) args->no_final_decision = atoi(values[0]); return 0; } #ifdef WITH_ZMQ if (!strcmp(key, "zmq")) { args->zmq = 1; if (value_count == 1) args->zmq = atoi(values[0]); return 0; } if (!strcmp(key, "zmq_port")) { args->zmq_port = DEFAULT_ZMQ_PORT; if (value_count < 1) { fprintf(stderr, "--zmq_port missing value\n"); return -1; } args->zmq_port = atoi(values[0]); return 0; } if (!strcmp(key, "zmq_iface")) { if (value_count < 1) { fprintf(stderr, "--zmq_iface missing interface name\n"); return -1; } args->zmq_iface = values[0]; return 0; } if (!strcmp(key, "zmq_transport")) { if (value_count != 1) { fprintf(stderr, "--zmq_transport missing value\n"); return -1; } args->zmq_transport = values[0]; return 0; } #endif // WITH_ZMQ if (!strcmp(key, "output") || !strcmp(key, "output_path")) { if (value_count == 1) { args->output_path = values[0]; return 0; } fprintf(stderr, "--output_path missing path value\n"); return -1; } if (!strcmp(key, "match_output_path")) { if (value_count == 1) { args->match_output_path = values[0]; return 0; } fprintf(stderr, "--match_output_path missing path value\n"); return -1; } if (!strcmp(key, "steps_output_path")) { if (value_count == 1) { args->steps_output_path = values[0]; return 0; } fprintf(stderr, "--steps_output_path missing path value\n"); return -1; } if (!strcmp(key, "obstruct_output_path")) { if (value_count == 1) { args->obstruct_output_path = values[0]; return 0; } fprintf(stderr, "--obstruct_output_path missing path value\n"); return -1; } if (!strcmp(key, "template_output_path")) { if (value_count == 1) { args->template_output_path = values[0]; return 0; } fprintf(stderr, "--template_output_path missing path value\n"); return -1; } if (!strcmp(key, "input") || !strcmp(key, "template")) { if (value_count == 0) { fprintf(stderr, "--template missing value\n"); return -1; } for (i = 0; i < value_count; i++) { if (args->input_count >= MAX_INPUT_TEMPLATES) { fprintf(stderr, "Max template input reached %d\n", MAX_INPUT_TEMPLATES); return -1; } args->inputs[args->input_count] = values[i]; args->input_count++; } return 0; } #ifdef WITH_RFID if (!strcmp(key, "rfid_in")) { if (value_count == 1) { args->rfid_inner_path = values[0]; return 0; } fprintf(stderr, "--rfid_in missing path value\n"); return -1; } if (!strcmp(key, "rfid_out")) { if (value_count == 1) { args->rfid_outer_path = values[0]; return 0; } fprintf(stderr, "--rfid_out missing path value\n"); return -1; } if (!strcmp(key, "rfid_allowed")) { if (value_count == 1) { if (catcierge_create_rfid_allowed_list(args, values[0])) { CATERR("Failed to create RFID allowed list\n"); return -1; } return 0; } fprintf(stderr, "--rfid_allowed missing comma separated list of values\n"); return -1; } if (!strcmp(key, "rfid_time")) { if (value_count == 1) { args->rfid_lock_time = (double)atof(values[0]); return 0; } fprintf(stderr, "--rfid_time missing seconds value (float)\n"); return -1; } if (!strcmp(key, "rfid_lock")) { args->lock_on_invalid_rfid = 1; if (value_count == 1) args->lock_on_invalid_rfid = atoi(values[0]); return 0; } #endif // WITH_RFID if (!strcmp(key, "log")) { if (value_count == 1) { args->log_path = values[0]; return 0; } fprintf(stderr, "--log missing path value\n"); return -1; } if (!strcmp(key, "match_cmd")) { if (value_count == 1) { args->match_cmd = values[0]; return 0; } fprintf(stderr, "--match_cmd missing value\n"); return -1; } if (!strcmp(key, "save_img_cmd")) { if (value_count == 1) { args->save_img_cmd = values[0]; return 0; } fprintf(stderr, "--save_img_cmd missing value\n"); return -1; } if (!strcmp(key, "frame_obstructed_cmd")) { if (value_count == 1) { args->frame_obstructed_cmd = values[0]; return 0; } fprintf(stderr, "--frame_obstructed_cmd missing value\n"); return -1; } if (!strcmp(key, "save_imgs_cmd") || !strcmp(key, "match_group_done_cmd")) { if (value_count == 1) { args->match_group_done_cmd = values[0]; return 0; } fprintf(stderr, "--match_group_done_cmd missing value\n"); return -1; } if (!strcmp(key, "match_done_cmd")) { if (value_count == 1) { args->match_done_cmd = values[0]; return 0; } fprintf(stderr, "--match_done_cmd missing value\n"); return -1; } if (!strcmp(key, "do_lockout_cmd")) { if (value_count == 1) { args->do_lockout_cmd = values[0]; return 0; } fprintf(stderr, "--do_lockout_cmd missing value\n"); return -1; } if (!strcmp(key, "do_unlock_cmd")) { if (value_count == 1) { args->do_unlock_cmd = values[0]; return 0; } fprintf(stderr, "--do_unlock cmd missing value\n"); return -1; } if (!strcmp(key, "state_change_cmd")) { if (value_count == 1) { args->state_change_cmd = values[0]; return 0; } fprintf(stderr, "--state_change_cmd cmd missing value\n"); return -1; } if (!strcmp(key, "nocolor")) { args->nocolor = 1; if (value_count == 1) args->nocolor = atoi(values[0]); return 0; } if (!strcmp(key, "noanim")) { args->noanim = 1; if (value_count == 1) args->noanim = atoi(values[0]); return 0; } if (!strcmp(key, "save_steps")) { args->save_steps = 1; if (value_count == 1) args->save_steps = atoi(values[0]); return 0; } if (!strcmp(key, "chuid")) { if (value_count == 1) { args->chuid = values[0]; return 0; } fprintf(stderr, "--chuid missing value\n"); return -1; } #ifdef WITH_RFID if (!strcmp(key, "rfid_detect_cmd")) { if (value_count == 1) { args->rfid_detect_cmd = values[0]; return 0; } fprintf(stderr, "--rfid_detect_cmd missing value\n"); return -1; } if (!strcmp(key, "rfid_match_cmd")) { if (value_count == 1) { args->rfid_match_cmd = values[0]; return 0; } fprintf(stderr, "--rfid_match_cmd missing value\n"); return -1; } #endif // WITH_RFID #ifndef _WIN32 // TODO: Support this on windows. if (!strcmp(key, "base_time")) { if (value_count == 1) { struct tm base_time_tm; time_t base_time_t; struct timeval base_time_now; long base_time_diff; memset(&base_time_tm, 0, sizeof(base_time_tm)); memset(&base_time_now, 0, sizeof(base_time_now)); args->base_time = values[0]; if (!strptime(args->base_time, "%Y-%m-%dT%H:%M:%S", &base_time_tm)) { goto fail_base_time; } if ((base_time_t = mktime(&base_time_tm)) == -1) { goto fail_base_time; } gettimeofday(&base_time_now, NULL); base_time_diff = base_time_now.tv_sec - base_time_t; catcierge_strftime_set_base_diff(base_time_diff); return 0; fail_base_time: fprintf(stderr, "Failed to parse --base_time %s\n", values[0]); return -1; } fprintf(stderr, "--base_time missing value\n"); return -1; } #endif // _WIN32 #ifdef RPI if (!strncmp(key, "rpi-", 4)) { int rpiret = 0; const char *rpikey = key + strlen("rpi"); if (!raspicamcontrol_parse_cmdline(&args->rpi_settings.camera_parameters, rpikey, (value_count == 1) ? values[0] : NULL)) { return -1; } return 0; } #endif // RPI return -1; }
static int catcierge_rfid_read(catcierge_rfid_t *rfid) { int ret = 0; int is_error = 0; int errorcode; const char *error_msg = NULL; if ((rfid->bytes_read = read(rfid->fd, rfid->buf, sizeof(rfid->buf) - 1)) < 0) { if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) { CATERR("%s RFID Reader: Read error %d, %s\n", rfid->name, errno, strerror(errno)); ret = -1; goto fail; } CATERR("%s RFID Reader: Need more\n"); // TODO: Add CAT_NEED_MORE state here and handle that. return -1; } // Get rid of any trailing CRLF. if (rfid->buf[rfid->bytes_read - 1] == '\n') rfid->bytes_read--; if (rfid->buf[rfid->bytes_read - 1] == '\r') rfid->bytes_read--; rfid->buf[rfid->bytes_read] = '\0'; CATLOG("%s RFID Reader: %ld bytes: %s\n", rfid->name, rfid->bytes_read, rfid->buf); if (rfid->bytes_read == 0) { // TODO: EOF, do something special here? return 0; } // Check for error. if (rfid->buf[0] == '?') { is_error = 1; errorcode = atoi(&rfid->buf[1]); error_msg = catcierge_rfid_error_str(errorcode); CATERR("%s RFID reader: error %d on read, %s\n", rfid->name, errorcode, error_msg); // TODO: Hmm should we really just fall through here in all cases? } if (rfid->state == CAT_CONNECTED) { CATLOG("%s RFID Reader: Started listening for cats on %s\n", rfid->name, rfid->serial_path); rfid->state = CAT_AWAITING_TAG; } else if (rfid->state == CAT_AWAITING_TAG) { if (!is_error) { int complete = (rfid->bytes_read >= 15); rfid->cb(rfid, complete, rfid->buf, rfid->bytes_read, rfid->user); } else { CATERR("%s RFID Reader: Failed reading tag, %s\n", rfid->name, error_msg); } } else { CATERR("%s RFID Reader: Invalid state on read, %d\n", rfid->name, rfid->state); } fail: rfid->bytes_read = 0; rfid->offset = 0; return ret; }
int catcierge_haar_matcher_init(catcierge_matcher_t **octx, catcierge_matcher_args_t *oargs) { catcierge_haar_matcher_t *ctx = NULL; catcierge_haar_matcher_args_t *args = (catcierge_haar_matcher_args_t *)oargs; assert(args); assert(octx); if (!(*octx = calloc(1, sizeof(catcierge_haar_matcher_t)))) { CATERR("Out of memory!\n"); return -1; } ctx = (catcierge_haar_matcher_t *)*octx; ctx->super.type = MATCHER_HAAR; ctx->super.name = "Haar Cascade"; ctx->super.short_name = "haar"; if (!args->cascade) { CATERR("Haar matcher: No cascade xml specified. Use --cascade\n"); return -1; } if (!(ctx->cascade = cv2CascadeClassifier_create())) { CATERR("Failed to create cascade classifier.\n"); goto opencv_error; } if (cv2CascadeClassifier_load(ctx->cascade, args->cascade)) { CATERR("Failed to load cascade xml: %s\n", args->cascade); return -1; } if (!(ctx->storage = cvCreateMemStorage(0))) { goto opencv_error; } // TOOD: Make args for kernel sizes. Rename the kernels for what they do instead if (!(ctx->kernel2x2 = cvCreateStructuringElementEx(2, 2, 0, 0, CV_SHAPE_RECT, NULL))) { goto opencv_error; } if (!(ctx->kernel3x3 = cvCreateStructuringElementEx(3, 3, 0, 0, CV_SHAPE_RECT, NULL))) { goto opencv_error; } if (!(ctx->kernel5x1 = cvCreateStructuringElementEx(5, 1, 0, 0, CV_SHAPE_RECT, NULL))) { goto opencv_error; } ctx->args = args; ctx->super.debug = args->debug; ctx->super.match = catcierge_haar_matcher_match; ctx->super.decide = catcierge_haar_matcher_decide; ctx->super.translate = catcierge_haar_matcher_translate; return 0; opencv_error: CATERR("OpenCV error\n"); return -1; }
void catcierge_run(char *command) { #ifndef _WIN32 { char *argv[4] = {0}; pid_t pid; argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = command; argv[3] = NULL; // Fork a child process. if ((pid = fork()) < 0) { CATERR("Forking child process failed: %d, %s\n", errno, strerror(errno)); } else if (pid == 0) { // For the child process. // Execute the command. if (execvp(*argv, argv) < 0) { CATERR("Exec \"%s\" failed: %d, %s\n", command, errno, strerror(errno)); exit(1); } } else { CATLOG("Called program \"%s\"\n", command); } } #else // _WIN32 { char tmp[4096]; STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, 0, sizeof(si)); si.dwXSize = sizeof(si); memset(&pi, 0, sizeof(pi)); snprintf(tmp, sizeof(tmp) - 1, "c:\\Windows\\system32\\cmd.exe /c %s", command); if (!CreateProcess( NULL, tmp, // Commandline NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi )) // Pointer to PROCESS_INFORMATION structure { CATERR("Error %d, Failed to run command %s\n", GetLastError(), command); } else { CATLOG("Called program \"%s\"\n", command); } } #endif // _WIN32 }
int catcierge_template_matcher_init(catcierge_matcher_t **octx, catcierge_matcher_args_t *oargs) { int i; CvSize snout_size; CvSize matchres_size; IplImage *snout_prep = NULL; const char **snout_paths = NULL; int snout_count; catcierge_template_matcher_t *ctx = NULL; catcierge_template_matcher_args_t *args = (catcierge_template_matcher_args_t *)oargs; assert(args); assert(octx); if (!(*octx = calloc(1, sizeof(catcierge_template_matcher_t)))) { CATERR("Out of memory!\n"); return -1; } ctx = (catcierge_template_matcher_t *)*octx; if (args->snout_count == 0) return -1; ctx->super.type = MATCHER_TEMPLATE; ctx->args = args; snout_paths = args->snout_paths; snout_count = args->snout_count; ctx->match_flipped = args->match_flipped; ctx->match_threshold = args->match_threshold; ctx->low_binary_thresh = CATCIERGE_LOW_BINARY_THRESH_DEFAULT; ctx->high_binary_thresh = CATCIERGE_HIGH_BINARY_THRESH_DEFAULT; // TODO: Make these setable instead. ctx->width = CATCIERGE_DEFAULT_RESOLUTION_WIDTH; ctx->height = CATCIERGE_DEFUALT_RESOLUTION_HEIGHT; for (i = 0; i < snout_count; i++) { if (access(snout_paths[i], F_OK) == -1) { fprintf(stderr, "No such file %s\n", snout_paths[i]); return -1; } } if (!(ctx->storage = cvCreateMemStorage(0))) { return -1; } if (!(ctx->kernel = cvCreateStructuringElementEx(3, 3, 0, 0, CV_SHAPE_RECT, NULL))) { return -1; } ctx->snout_count = snout_count; // Load the snout images. ctx->snouts = (IplImage **)calloc(snout_count, sizeof(IplImage *)); ctx->flipped_snouts = (IplImage **)calloc(snout_count, sizeof(IplImage *)); ctx->matchres = (IplImage **)calloc(snout_count, sizeof(IplImage *)); if (!ctx->snouts || !ctx->flipped_snouts || !ctx->matchres) { fprintf(stderr, "Template matcher: Out of memory!\n"); return -1; } for (i = 0; i < snout_count; i++) { if (!(snout_prep = cvLoadImage(snout_paths[i], 1))) { fprintf(stderr, "Failed to load snout image: %s\n", snout_paths[i]); return -1; } snout_size = cvGetSize(snout_prep); if (!(ctx->snouts[i] = cvCreateImage(snout_size, 8, 1))) { cvReleaseImage(&snout_prep); return -1; } if (_catcierge_prepare_img(ctx, snout_prep, ctx->snouts[i])) { fprintf(stderr, "Failed to prepare snout image: %s\n", snout_paths[i]); return -1; } // Flip so we can match for going out as well (and not fail the match). ctx->flipped_snouts[i] = cvCloneImage(ctx->snouts[i]); cvFlip(ctx->snouts[i], ctx->flipped_snouts[i], 1); // Setup a matchres image for each snout // (We can share these for normal and flipped snouts). matchres_size = cvSize(ctx->width - snout_size.width + 1, ctx->height - snout_size.height + 1); ctx->matchres[i] = cvCreateImage(matchres_size, IPL_DEPTH_32F, 1); cvReleaseImage(&snout_prep); } ctx->super.match = catcierge_template_matcher_match; ctx->super.decide = caticerge_template_matcher_decide; ctx->super.translate = catcierge_template_matcher_translate; return 0; }
int main(int argc, char **argv) { catcierge_args_t *args = &grb.args; fprintf(stderr, "\nCatcierge Grabber v" CATCIERGE_VERSION_STR " (" CATCIERGE_GIT_HASH_SHORT ""); // Was this built with changes in the git sources? #ifdef CATCIERGE_GIT_TAINTED fprintf(stderr, "-tainted"); #endif fprintf(stderr, ")\n(C) Joakim Soderberg 2013-2016\n\n"); fprintf(stderr, "Library versions:\n"); fprintf(stderr, " OpenCV v%d.%d.%d\n", CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION); #ifdef WITH_ZMQ fprintf(stderr, " CZMQ v%d.%d.%d\n", CZMQ_VERSION_MAJOR, CZMQ_VERSION_MINOR, CZMQ_VERSION_PATCH); #endif fprintf(stderr, "\n"); // TODO: Enable specifying pid path on command line. #ifndef _WIN32 pid_fd = create_pid_file(argv[0], PID_PATH, FD_CLOEXEC); #endif if (catcierge_grabber_init(&grb)) { fprintf(stderr, "Failed to init\n"); return -1; } if (catcierge_args_init(args, argv[0])) { fprintf(stderr, "Failed to init args\n"); return -1; } if (catcierge_args_parse(args, argc, argv)) { return -1; } if (args->nocolor) { catcierge_nocolor = 1; } catcierge_print_settings(args); setup_sig_handlers(); if (args->log_path) { if (!(grb.log_file = fopen(args->log_path, "a+"))) { CATERR("Failed to open log file \"%s\"\n", args->log_path); } } #ifdef RPI if (catcierge_setup_gpio(&grb)) { CATERR("Failed to setup GPIO pins\n"); return -1; } CATLOG("Initialized GPIO pins\n"); #endif // RPI assert((args->matcher_type == MATCHER_TEMPLATE) || (args->matcher_type == MATCHER_HAAR)); if (catcierge_matcher_init(&grb.matcher, catcierge_get_matcher_args(args))) { CATERR("Failed to init %s matcher\n", grb.matcher->name); return -1; } CATLOG("Initialized catcierge image recognition\n"); if (catcierge_output_init(&grb, &grb.output)) { CATERR("Failed to init output template system\n"); return -1; } if (catcierge_output_load_templates(&grb.output, args->inputs, args->input_count)) { CATERR("Failed to load output templates\n"); return -1; } CATLOG("Initialized output templates\n"); #ifdef WITH_RFID catcierge_init_rfid_readers(&grb); #endif catcierge_setup_camera(&grb); #ifdef WITH_ZMQ catcierge_zmq_init(&grb); #endif CATLOG("Starting detection!\n"); // TODO: Create a catcierge_grb_start(grb) function that does this instead. catcierge_fsm_start(&grb); // Run the program state machine. do { if (!catcierge_timer_isactive(&grb.frame_timer)) { catcierge_timer_start(&grb.frame_timer); } // Always feed the RFID readers. #ifdef WITH_RFID if ((args->rfid_inner_path || args->rfid_outer_path) && catcierge_rfid_ctx_service(&grb.rfid_ctx)) { CATERRFPS("Failed to service RFID readers\n"); } #endif // WITH_RFID grb.img = catcierge_get_frame(&grb); catcierge_run_state(&grb); catcierge_print_spinner(&grb); } while ( grb.running #ifdef WITH_ZMQ && !zctx_interrupted #endif ); catcierge_matcher_destroy(&grb.matcher); catcierge_output_destroy(&grb.output); catcierge_destroy_camera(&grb); #ifdef WITH_ZMQ catcierge_zmq_destroy(&grb); #endif catcierge_grabber_destroy(&grb); catcierge_args_destroy(&grb.args); if (grb.log_file) { fclose(grb.log_file); } #ifndef _WIN32 if (pid_fd > 0) { close(pid_fd); unlink(PID_PATH); } #endif return 0; }