// This tests the different lockout strategies.
static char *run_lockout_tests(catcierge_grb_t *grb, int obstruct,
	catcierge_lockout_method_t lockout_method)
{
	catcierge_args_t *args = &grb->args;

	switch (lockout_method)
	{
		case OBSTRUCT_OR_TIMER_3:
			if (obstruct == 1)
			{
				// Obstruct and then un-obstruct.
				catcierge_test_STATUS("Lockout method: Obstruct or timer. Obstruct,"
					" then un-obstruct should result in unlock");

				load_test_image_and_run(grb, 1, 2); // Obstruct.
				mu_assert("Expected LOCKOUT state after obstruction",
					(grb->state == catcierge_state_lockout));

				load_test_image_and_run(grb, 1, 5); // Clear frame.
				mu_assert("Expected WAITING state after clear frame",
					(grb->state == catcierge_state_waiting));
			}
			else if (obstruct == 2)
			{
				// Keep on obstructing. Timer should unlock.
				catcierge_test_STATUS("Lockout method: Obstruct or timer. "
					"Continous obstruction, %d second timer should result in unlock",
					args->lockout_time + 1);

				load_test_image_and_run(grb, 1, 2); // Obstruct.
				mu_assert("Expected LOCKOUT state after obstruction",
					(grb->state == catcierge_state_lockout));

				sleep(args->lockout_time + 1);
				
				//catcierge_run_state(grb);
				load_test_image_and_run(grb, 1, 2);
				mu_assert("Expected WAITING state after timeout",
					(grb->state == catcierge_state_waiting));
			}
			else
			{
				catcierge_test_STATUS("Lockout method: Obstruct or timer. "
					"No obstruction. Sleeping %d seconds should result in unlock",
					args->lockout_time + 1);

				sleep(args->lockout_time + 1);

				// Clear frame.
				load_test_image_and_run(grb, 1, 5);
				mu_assert("Expected WAITING stat after timeout",
					(grb->state == catcierge_state_waiting));
			}
			break;
		case OBSTRUCT_THEN_TIMER_2:
			if (obstruct == 1)
			{
				catcierge_test_STATUS("Lockout method: Obstruct then Timer. "
					"%d second timer should start after obstruction has ended",
					args->lockout_time + 1);

				load_test_image_and_run(grb, 1, 2); // Obstruct.
				mu_assert("Expected LOCKOUT state after obstruction",
					(grb->state == catcierge_state_lockout));

				load_test_image_and_run(grb, 1, 5); // Clear frame.
				mu_assert("Expected LOCKOUT state after clear frame",
					(grb->state == catcierge_state_lockout));

				sleep(1);

				mu_assert("Expected LOCKOUT state after 1 second clear frame",
					(grb->state == catcierge_state_lockout));

				sleep(args->lockout_time);

				load_test_image_and_run(grb, 1, 5); // Clear frame.
				mu_assert("Expected WAITING state after clear frame and timeout",
					(grb->state == catcierge_state_waiting));

				catcierge_test_STATUS("Lockout timer value: %f seconds\n",
					catcierge_timer_get(&grb->lockout_timer));
			}
			else if (obstruct == 2)
			{
				catcierge_test_STATUS("Lockout method: Obstruct then Timer. "
					"Continous obstruction. Unlock should never happen");

				load_test_image_and_run(grb, 1, 2); // Obstruct.
				mu_assert("Expected LOCKOUT state after obstruction",
					(grb->state == catcierge_state_lockout));
				
				sleep(args->lockout_time + 1);
				
				load_test_image_and_run(grb, 1, 2); // Obstruct.
				mu_assert("Expected LOCKOUT state after timeout and"
					"continous obstruction",
					(grb->state == catcierge_state_lockout));

				catcierge_set_state(grb, catcierge_state_waiting);
			}
			else
			{
				catcierge_test_STATUS("Lockout method: Obstruct then Timer. "
					"No obstruction. %d second timer should unlock.",
					args->lockout_time + 1);

				load_test_image_and_run(grb, 1, 5); // Clear frame.
				mu_assert("Expected LOCKOUT state after clear frame",
					(grb->state == catcierge_state_lockout));

				sleep(args->lockout_time + 1);

				load_test_image_and_run(grb, 1, 5); // Clear frame.
				mu_assert("Expected WAITING state after clear frame and timeout",
					(grb->state == catcierge_state_waiting));
			}
			break;
		case TIMER_ONLY_1:
			// Sleep for unlock time and make sure we've unlocked.
			catcierge_test_STATUS("Lockout method: Timer only, sleep %d seconds",
				args->lockout_time + 1);

			sleep(args->lockout_time + 1);

			catcierge_run_state(grb);
			mu_assert("Expected WAITING state after timeout",
				(grb->state == catcierge_state_waiting));
			break;
	}

	return NULL;
}
Пример #2
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;
}