Keyboard Commands

From Distributed Autonomous and Networked Control Lab
Revision as of 17:21, 26 July 2016 by Jnoronha (talk | contribs) (Added command list timestamp)
Jump to navigation Jump to search

Keyboard commands give the user the ability to modify variables during a flight test. The actions each key performs is completely customizable and can trigger anything from just adjusting a PID constant, to executing complex functions.

To get the basic idea of how the function works, here is a flow chart of the process and an example trigger:


List of Current Keyboard Commands

(Command List as of 7/26/16)

Movement Commands

  • 'w' - Moves Crazyflie1 Forward by 0.2 meters (- y setpoint) (COMMENTED OUT)
  • 's' - Moves Crazyflie1 Backward by 0.2 meters (+ y setpoint) (COMMENTED OUT)
  • 'a' - Moves Crazyflie1 Left by 0.2 meters (- x setpoint) (COMMENTED OUT)
  • 'd' - Moves Crazyflie1 Right by 0.2 meters (+ x setpoint) (COMMENTED OUT)
  • 'r' - Moves Crazyflie1 UP by 0.2 meters (+ z setpoint) (COMMENTED OUT)
  • 'f' - Moves Crazyflie1 Down by 0.2 meters (- z setpoint) (COMMENTED OUT)
  • '1' - Rotates Yaw of Crazyflie1 +45 degrees
  • '2' - Rotates Yaw of Crazyflie1 -45 degrees

Flight Mode Commands

  • 'k' - EMERGENCY STOP kill ALL Crazyflie engines (set all thrust to 0)
  • 'h' - Hand Mode (for ALL Crazyflies)
  • 'e' - Landing Mode (for ALL Crazyflies)
  • 't' - Crazyflie1 Take-Off
  • 'y' - Crazyflie2 Take-Off
  • 'u' - Crazyflie3 Take-Off
  • 'i' - Crazyflie4 Take-Off
  • 'h' - Hand Gesture Mode (for ALL Crazyflies)
  • 'm' - Mirror Mode (for ALL Crazyflies)

Utility Commands

  • ctrl+c - Quits Program, performs all cleanup.

Obsolete Key Commands

  • 'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
  • '`' - Enables TCP Server on the Swarm Client (for sending information to Swarm Clients on different computers)
  • 'l' - Enables TCP Client on the Swarm Client (for receiving information from Swarm Clients on different computers)
  • 'o' - Enable Flap Mode (used for testing Crazyflie Powered Flapping Wing Project)
  • '1' - Disable Flap Mode

Reading the Keyboard Input

We use the select() function for a non-blocking method to read the keyboard input from the STDIN file descriptor in linux. The function below is what we currently use to read the keyboard. (The function was provided by Dr. Phillip Jones):

1. First we need to establish the base functions that we will use to read the key input (code found in vrpn.cpp):


//////////////////////////////////////////////////
// kbhit                                        //
// Descption: used select to do a non blocking  //
// read of stdin.                               //
//                                              //
//////////////////////////////////////////////////
int kbhit()
{
    struct timeval tv;
    fd_set fds;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
    return FD_ISSET(STDIN_FILENO, &fds);
}

Then we can make it non-blocking code with the following:


//////////////////////////////////////////////////
// nonblock                                     //
// Descption: Turn off connoical mode so the    //
// user does not need to hit enter after        //
// pressing a key                               //
//                                              //
//////////////////////////////////////////////////
void nonblock(int state)
{
    struct termios ttystate;

    //get the terminal state
    tcgetattr(STDIN_FILENO, &ttystate);

    if (state==1)
    {
        //turn off canonical mode
        ttystate.c_lflag &= ~ICANON;
        //minimum of number input read.
        ttystate.c_cc[VMIN] = 1;
    }
    else if (state==0)
    {
        //turn on canonical mode
        ttystate.c_lflag |= ICANON;
    }
    //set the terminal attributes.
    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);

}

2. Reading the Keypress (code in vrpn.cpp):


nonblock(1);
usleep(1);
i = kbhit();		//keyboard hit (state change)

if (i!=0)               //If state has changed, read and record key value
{
	keystroke_now = fgetc(stdin);
    if (keystroke_now == 'q')
	i=1;

else{
	i=0;
}

}   //END IF

readKeyboard();         //Uses key value input to trigger actions

All this code is doing is checking the STDIN file descriptor for a state change, if it has then read that change and record the key value that was pressed.
3. Using the Key value to trigger actions (code in vrpn.cpp):


void readKeyboard()
{
		//========Reads Keystrokes from Keyboard==========
	nonblock(1);
	if (keystroke_now != keystroke_prev) {  //If the keyvalue has changed (Debouncing safety)
/*
		if (keystroke_now == 'w') {
			yPositionDesired1 -= 0.2;
			cout << "New Y Setpoint: " << yPositionDesired1 << endl;
		} else if (keystroke_now == 's') {
			yPositionDesired1 += 0.2;
			cout << "New Y Setpoint: " << yPositionDesired1 << endl;
		} else if (keystroke_now == 'a') {
			xPositionDesired1 -= 0.2;
			cout << "New X Setpoint: " << xPositionDesired1 << endl;
		} else if (keystroke_now == 'd') {
			xPositionDesired1 += 0.2;
			cout << "New X Setpoint: " << xPositionDesired1 << endl;
		} else if (keystroke_now == 'r') {
			zPositionDesired1 += 0.2;
			cout << "New Z Setpoint: " << zPositionDesired1 << endl;
		} else if (keystroke_now == 'f') {
			zPositionDesired1 -= 0.2;
			cout << "New Z Setpoint: " << zPositionDesired1 << endl;
		} 
*/ //Commented out above inputs
		if (keystroke_now == '1') {
			yawDesired1 += 45.0;
			cout << "New Yaw Setpoint: " << yawDesired1 << endl;
		} else if (keystroke_now == '2') {
			yawDesired1 -= 45.0;
			cout << "New Yaw Setpoint: " << yawDesired1 << endl;
		} 
		else if (keystroke_now == 'k') {
				cflieCopter1->m_enumFlightMode = GROUNDED_MODE;
			if(cflieCopter2){
				cflieCopter2->m_enumFlightMode = GROUNDED_MODE;}
			if(cflieCopter3){
				cflieCopter3->m_enumFlightMode = GROUNDED_MODE;}
			if(cflieCopter4){
				cflieCopter4->m_enumFlightMode = GROUNDED_MODE;}

		} else if (keystroke_now == 'e') {
			cflieCopter1->m_enumFlightMode = LANDING_MODE;
		if(cflieCopter2){
			cflieCopter2->m_enumFlightMode = LANDING_MODE;}
		if(cflieCopter3){
			cflieCopter3->m_enumFlightMode = LANDING_MODE;}
		if(cflieCopter4){
			cflieCopter4->m_enumFlightMode = LANDING_MODE;}

			handMode = 0;
//			landingMode ^= 1;
//			mirrorMode = 0;
			cout << "Landing Mode Enabled" << endl;
		} else if (keystroke_now == 'm') {
			cflieCopter1->m_enumFlightMode = MIRROR_MODE;
		if(cflieCopter2){
			cflieCopter2->m_enumFlightMode = MIRROR_MODE;}
		if(cflieCopter3){
			cflieCopter3->m_enumFlightMode = MIRROR_MODE;}
		if(cflieCopter4){
			cflieCopter4->m_enumFlightMode = MIRROR_MODE;}
//			mirrorMode ^= 1;
			cout << "Mirror Mode Enabled" << endl;
		} else if (keystroke_now == 'h') {
			handMode = 1;

			cout << "Hand Mode Enabled" << endl;
		} else if (keystroke_now == 't') {
			cflieCopter1->m_enumFlightMode = TAKEOFF_MODE;
//			takeOff1 = 1;
			takeOffTime1 = cflieCopter1->currentTime() - initTime1;
		}
		else if (keystroke_now == 'y') {
			cflieCopter2->m_enumFlightMode = TAKEOFF_MODE;
//			takeOff2 = 1;
			takeOffTime2 = cflieCopter2->currentTime() - initTime2;
		}
		else if (keystroke_now == 'u') {
			cflieCopter3->m_enumFlightMode = TAKEOFF_MODE;
//			takeOff3 = 1;
			takeOffTime3 = cflieCopter3->currentTime() - initTime3;
		}
		else if (keystroke_now == 'i') {
			cflieCopter4->m_enumFlightMode = TAKEOFF_MODE;
//			takeOff4 = 1;
			takeOffTime4 = cflieCopter4->currentTime() - initTime4;
		} 
//		else if (keystroke_now == '`') {
//			tcp_server_ON ^= 1;
//		} else if (keystroke_now == '1') {
//			tcp_client_ON ^= 1;
//		}
//		else if (keystroke_now == 'o') {
//			flap = 1;
//		}
//		else if (keystroke_now == 'l') {
//			flap = 0;
//		}
		
		keystroke_prev = keystroke_now;

	}

    nonblock(0);
}//END readKeyboard()

This is just a bunch of 'if' checks that activate if a certain key has been pressed.
  • So we can see that the first 8 options just simply add or subtract a constant value to a variable in the code whenever that key is pressed.
  • The options after that are what trigger different Flight Modes, telling the Crazyflie to do things like Take-Off, or to Fly in Formation, or to Land. These are more complex functions and can change the behavior of the entire swarm! See the Flight Modes page for more information on this.

Main Directory
Crazyflie Swarm Home | PC Client Software | USB Radio | Firmware | FAQ
Modifications Directory
Controller | Logging | Keyboard Commands | Changing Radio Channel | Flight Modes | Callbacks | Adding a Crazyflie | Firmware