void show_welcome() {
		while(m_usb.isConnected()) {
			m_con.clear();
			m_con << "****************************************" << endl;
			m_con << "*     Welcome to Self-Balance Robot    *" << endl;
			m_con << "*                 " VERSION "               *" << endl;
			m_con << "****************************************" << endl;
			m_con << "[1] Calibrations" << endl;
			m_con << "[2] PID Control tuning" << endl;
			m_con << "[3] Save changed" << endl;
			m_con << "[4] Load Default" << endl;
			m_con << "[5] Dashboard" << endl;
			switch(m_con.getc()) {
			case '1' :
				show_mpu6050();
				break;
			case '2' :
				show_pid();
				break;
			case '3' :
				saveConfigure();
				break;
			case '4' :
				setDefault();
				break;
			case '5':
				dashboard();
				break;
			case 'H':
				m_con.printf("High-Water Mark:%d\n", getStackHighWaterMark());
				m_con.getc();
				break;
			}
		}
	void dashboard() {
		while(m_usb.isConnected() ) {
			m_con.clear();
			m_con << "SetPoint Patch   Roll    PWM\%" << endl;
			m_con.printf("%0.3f\t %0.3f\t %0.3f\t%0.3f", m_robot->m_setpoint, m_robot->m_pitch, m_robot->m_roll, m_robot->m_output);
			if ( m_usb.available() ) {
				if ( m_con.getc()==0x1B ) return;
			}
			sleep(250);
		}
	void show_pid() {
		while( m_usb.isConnected() ) {
			m_con.clear();
			m_con << "****************************************" << endl;
			m_con << "*          PID Control tuning          *" << endl;
			m_con << "****************************************" << endl;
			m_con.printf("[1] Kp (%0.3f)\n", config.kp);
			m_con.printf("[2] Ki (%0.3f)\n", config.ki);
			m_con.printf("[3] Kd (%0.3f)\n", config.kd);
			m_con.printf("[4] Min. PWM (%0.2f)\n", config.pwm_min);
			m_con.printf("[5] Max. PWM (%0.2f)\n", config.pwm_max);
			m_con.printf("[6] Skip Interval (%0.4f)\n", config.skip_interval);
			m_con << "[ESC] Return" << endl;
			switch(m_con.getc()) {
			case '1':
				m_con << "Input Kp:" << flush;
				config.kp = m_usb.parseFloat(true);
				m_robot->tuings(config.kp, config.ki, config.kd);
				break;
			case '2':
				m_con << "Input Ki:" << flush;
				config.ki = m_usb.parseFloat(true);
				m_robot->tuings(config.kp, config.ki, config.kd);
				break;
			case '3':
				m_con << "Input Kd:" << flush;
				config.kd = m_usb.parseFloat(true);
				m_robot->tuings(config.kp, config.ki, config.kd);
				break;
			case '4':
				m_con << "Input Min. PWM:" << flush;
				config.pwm_min = m_usb.parseFloat(true);
				break;
			case '5':
				m_con << "Input Max. PWM:" << flush;
				config.pwm_max = m_usb.parseFloat(true);
				break;
			case '6':
				m_con << "Input Skip Interval:" << flush;
				config.skip_interval = m_usb.parseFloat(true);
				break;
			case 0x1B:
				return;
			}
		}
	void show_mpu6050() {
		while( m_usb.isConnected() ) {
			m_con.clear();
			m_con << "****************************************" << endl;
			m_con << "*            Calibrations              *" << endl;
			m_con << "****************************************" << endl;
#if USE_AUTO_TUNING
			m_con.printf("[1] Set roll angle (%0.4f)\n", config.roll_offset);
#else
			m_con.printf("[1] Set roll offset (%0.4f)\n", config.roll_offset);
#endif
			m_con.printf("[2] Set left motor power (%0.2f)\n", config.left_power);
			m_con.printf("[3] Set right motor power (%0.2f)\n", config.right_power);
			m_con << "[ESC] Return" << endl;

			switch( m_con.getc() ) {
			case '1':
#if USE_AUTO_TUNING
				m_con << "Input roll angle:" << flush;
#else
				m_con << "Input roll offset:" << flush;
#endif
				config.roll_offset = m_usb.parseFloat(true);
				break;
			case '2':
				m_con << "Input left power:" << flush;
				config.left_power = m_usb.parseFloat(true);
				break;
			case '3':
				m_con << "Input right power:" << flush;
				config.right_power = m_usb.parseFloat(true);
				break;
			case 0x1B:
				return;
			}
		}
void UserSortState::activate() {
	Console* console = Console::getInstance();
	SortWrapper sortFascade;
	srand(time(NULL));

	bool exit = false;
	while (!exit) {
		string input = "";
		console->clear();
		console->put("[run] run a sort");
		console->put("[back] return to main screen");
		console->put("please enter your desired option: ");
		input = console->get();
		if (input == "back") {
			exit = true;
		}
		else if (input == "run") {
			int n = 0;
			console->put("how many elements would you like to sort: ");
			n = console->str_to_int(console->get());
			vector<int> vectorToSort;
			for (int i = 0; i < n; i++) {
				vectorToSort.push_back(rand() % RAND_MAX);
			}

			string ascendingInput = "";
			while (ascendingInput != "asc" && ascendingInput != "des") {
				console->put("[asc]ending or [des]cending: ");
				ascendingInput = console->get();
			}
			bool ascending = (ascendingInput == "asc");

			string typeInput = "";
			while (typeInput != "sel" && typeInput != "ins" && typeInput != "she" && typeInput != "qui" && typeInput != "mer" && typeInput != "hm" && typeInput != "hq") {
				console->put("which type of sort?");
				console->put("[sel]ection, [ins]ertion, [she]ll, [mer]ge, [qui]ck, [hm]-hybrid merge, or [hq]-hybrid quick: ");
				typeInput = console->get();
			}
			SortType sortType;
			if (typeInput == "sel") {
				sortType = SELECTION;
			}
			else if (typeInput == "ins") {
				sortType = INSERTION;
			}
			else if (typeInput == "she") {
				sortType = SHELL;
			}
			else if (typeInput == "mer") {
				sortType = MERGE;
			}
			else if (typeInput == "qui") {
				sortType = QUICK;
			}
			else if (typeInput == "hm") {
				sortType = HYBRID_MERGE;
			}
			else if (typeInput == "hq") {
				sortType = HYBRID_QUICK;
			}

			int hybridThreshold = 0;
			if (sortType == HYBRID_MERGE || sortType == HYBRID_QUICK) {
				console->put("how large do you want the hybrid threshold to be: ");
				hybridThreshold = console->str_to_int(console->get());
			}

			SortParams params;
			params.ascending = ascending;
			params.sortType = sortType;
			params.hybridThreshold = hybridThreshold;
			console->put("running sort, depending on how many elements you chose this may take some time");

			int memBefore = MemoryTracker::get_current_memory();
			int ticksBefore = clock();
			sortFascade.sort(vectorToSort, params);
			int ticksAfter = clock();
			int timeElapsed = (ticksAfter - ticksBefore)/(CLOCKS_PER_SEC/1000);
			int memUsed = MemoryTracker::get_saved_memory() - memBefore;

			bool success = true;
			for (vector<int>::iterator sortedIt = vectorToSort.begin(); sortedIt != vectorToSort.end(); sortedIt++) {
				vector<int>::iterator next = sortedIt + 1;
				if (next != vectorToSort.end()) {
					if (params.ascending) {
						if (*next < *sortedIt) {
							success = false;
							break;
						}
					}
					else {
						if (*next > *sortedIt) {
							success = false;
							break;
						}
					}
				}
			}

			string successString = (success) ? ("successfull") : ("not successfull");
			console->put("the sort was "+successString+", took "+console->int_to_str(timeElapsed)+"ms to complete and used "+console->int_to_str(memUsed)+" bytes");
			console->pause();
		}
		else {
			console->put("\""+input+"\" is not recognized as a valid input");
			console->pause();
		}
	}
}