void ardronewin32_recover(int send)
{
	if (send == 1)
		ardrone_tool_set_ui_pad_select(1);
	else
		ardrone_tool_set_ui_pad_select(0);
}
C_RESULT ardrone_control() {
    const char * linefiller="                                              ";
    static int nCountFrequency=0;
    static bool function_first_call = true;
    nCountFrequency++;
    if(nCountFrequency%50==0)
    {
        printf("过去了  %d    秒!!!!\n",nCountFrequency/50);
        if(nCountFrequency%5000==0)
            nCountFrequency=0;
    }
    if (function_first_call) {
        printf("Sending flat trim - make sure the drone is horizontal at client startup.\n");
        ardrone_at_set_flat_trim(); //向无人机发送确定无人机是水平躺着,每次无人机启动都要发送,不可在无人机飞行时调用此函数
        function_first_call=false;
        //	vp_os_memcpy(previous_keyboardState,keyboardState,sizeof(keyboardState));
        return C_OK;

    }

    ARWin32Demo_AcquireConsole();
    ARWin32Demo_SetConsoleCursor(0,12);

    if(emergency!=emergency_p) { //以下代码 待服务器端完成后,需再次修改
        if(emergency=0)
        {
            ardrone_tool_set_ui_pad_start(0);
            ardrone_tool_set_ui_pad_select(1);
            printf("Sending emergency.%s\n",linefiller);
        }
        else//若之前按下,现在没按,说明是emergency状态转常规飞行
        {
            ardrone_tool_set_ui_pad_select(0);
        }
    }

    if((takeoff!=takeoff_p)&&takeoff==1)
    {
        start^=1;
        ardrone_tool_set_ui_pad_start(start);
        printf("飞机起飞 %i.%s\n",start,linefiller);
    }
    if((trim!=trim_p)&&trim==1)
    {
        ardrone_at_set_flat_trim();
        printf("水平矫正.%s\n",linefiller);
    }

    ardrone_at_set_progress_cmd(hover,roll, pitch, gaz, yaw);
    printf("[Pitch %f] [Roll %f] [Yaw %f] [Gaz %f]%\n",pitch,roll,yaw,gaz);

    ARWin32Demo_ReleaseConsole();

    return C_OK;
}
示例#3
0
C_RESULT update_teleop(void)
{
	// This function *toggles* the emergency state, so we only want to toggle the emergency
	// state when we are in the emergency state (because we want to get out of it).
	ardrone_tool_set_ui_pad_select(needs_reset);
	needs_reset = false;

	// This function sets whether or not the robot should be flying.  If it is flying and you
	// send 0, the robot will slow down the motors and slowly descend to the floor.
	ardrone_tool_set_ui_pad_start(is_flying);

	float left_right = cmd_vel.linear.y;
	float front_back = cmd_vel.linear.x;
	float up_down = cmd_vel.linear.z;
	float turn = cmd_vel.angular.z;

	///printf("LR:%f FB:%f UD:%f TURN:%f\n", left_right, front_back, up_down, turn);
	if(left_right == 0 && front_back == 0 && up_down == 0 && turn == 0)
    {
        printf("Drone im Hover Mode\n");
        ardrone_at_set_progress_cmd(0, left_right, front_back, up_down, turn);
    }else{
        ardrone_at_set_progress_cmd(1, left_right, front_back, up_down, turn);
    }

	return C_OK;
}
	int _stdcall SendEmergency()
	{
		ardrone_tool_set_ui_pad_start(0); 
		ardrone_tool_set_ui_pad_select(1);  
		need_update = TRUE;
		printf("Sent Emergency\n");
		return 0;
	}
示例#5
0
DEFINE_THREAD_ROUTINE(drone_main_thread, data) {
  ardrone_tool_set_ui_pad_select(0); // Do not send any emergency signal
  ardrone_at_set_navdata_all();

//  Uint32 emergencyPulseStartTime = SDL_GetTicks() + EMERGENCY_SIGNAL_PULSE_DURATION;
//
//  int doRun = 1;
//
//  while (doRun) {
//    ardrone_tool_update();
//
//    pthread_mutex_lock(&drone_sharedDataMutex);
//    int emergencyPulseMS = SDL_GetTicks() - emergencyPulseStartTime;
//    if ((drone_emergency != drone_targetEmergency) && ((emergencyPulseMS > 2 * EMERGENCY_SIGNAL_PULSE_DURATION) || (emergencyPulseMS < EMERGENCY_SIGNAL_PULSE_DURATION))) {
//      ardrone_tool_set_ui_pad_select(1);
//
//      if (emergencyPulseMS > 2 * EMERGENCY_SIGNAL_PULSE_DURATION) {
//        emergencyPulseStartTime = SDL_GetTicks();
//      }
//    } else {
//      ardrone_tool_set_ui_pad_select(0);
//    }
//
//    doRun = drone_doRun;
//    pthread_mutex_unlock(&drone_sharedDataMutex);
//  }
//
  Uint32 startTime;

  // Enforce landing...
  startTime = SDL_GetTicks();
  while ((!drone_landed) && (SDL_GetTicks() - startTime < DRONE_LAND_WAIT_LIMIT)) {
    drone_land();
    ardrone_tool_update();
  }
  if (!drone_landed) {
    fprintf(stderr, "Warning! Drone could not land within %d seconds! Trying to set emergency flag...\n", DRONE_LAND_WAIT_LIMIT / 1000);
    startTime = SDL_GetTicks();
    while ((!(drone_emergency) || (drone_landed)) && (SDL_GetTicks() - startTime < DRONE_EMERGENCY_WAIT_LIMIT)) {
      drone_setEmergency(1);
      ardrone_tool_update();
    }

    if ((!(drone_emergency) || (drone_landed))) {
      fprintf(stderr, "Error! Drone could not land and no emergency flag could be set. If it is still flying: Good luck!\n");
    }
  }

  return 0;
}
示例#6
0
C_RESULT update_teleop(void)
{
	// This function *toggles* the emergency state, so we only want to toggle the emergency
	// state when we are in the emergency state (because we want to get out of it).
	//fprintf(stderr, "%d\n", int(needs_reset));
	if (needs_reset)
	{
	//	fprintf(stderr, "needs_reset true\n");
		ardrone_tool_set_ui_pad_select(needs_reset);
		needs_reset = false;
	//	fprintf(stderr, "needs_reset false\n");
	}

	// ******dep****** This function sets whether or not the robot should be flying.  If it is flying and you
	// ******dep****** send 0, the robot will slow down the motors and slowly descend to the floor.
	//rujian July 30
	if (needs_takeoff)
	{
		ardrone_tool_set_ui_pad_start(true);
		needs_takeoff = false;
	}

	if (needs_land)
	{
		ardrone_tool_set_ui_pad_start(false);
		needs_land = false;
	}

	float left_right = cmd_vel.linear.y;
	float front_back = cmd_vel.linear.x;
	float up_down = cmd_vel.linear.z;
	float turn = cmd_vel.angular.z;

	ardrone_at_set_progress_cmd(do_not_hover, left_right, front_back, up_down, turn);	//rujian July27
	return C_OK;
}
示例#7
0
C_RESULT update_dx_gamepad(void)
{
 /* static int32_t x = 0, y = 0;
  static bool_t refresh_values = FALSE;
  size_t res;
  static js_event js_e_buffer[64];
 */
  
	
	HRESULT hr;
    TCHAR strText[512] = {0}; // Device state text

	/* Direct Input gamepad state */
		DIJOYSTATE2 js;           
		static DIJOYSTATE2 previous_js;         

	static bool function_first_call = true;
	static float roll = 0, pitch = 0, gaz=0, yaw=0;

	const char * linefiller="                                              ";

	

 // Poll the device to read the current state
    hr = g_pJoystick->Poll();
    if( FAILED( hr ) )
    {
        // DInput is telling us that the input stream has been
        // interrupted. We aren't tracking any state between polls, so
        // we don't have any special reset that needs to be done. We
        // just re-acquire and try again.
        hr = g_pJoystick->Acquire();
        while( hr == DIERR_INPUTLOST )
            hr = g_pJoystick->Acquire();

        // hr may be DIERR_OTHERAPPHASPRIO or other errors.  This
        // may occur when the app is minimized or in the process of 
        // switching, so just try again later 
        return C_OK;
    }

    // Get the input's device state
	if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof( DIJOYSTATE2 ), &js ) ) )
        return hr; // The device should have been acquired during the Poll()
	
	if (function_first_call) { 
		printf("Sending flat trim - make sure the drone is horizontal at client startup.\n"); 
		ardrone_at_set_flat_trim();
		function_first_call=false; 
		previous_js=js; 
		return C_OK; 
		
	}

	ARWin32Demo_AcquireConsole();
	ARWin32Demo_SetConsoleCursor(0,14);
	

	// Process the gamepad data
	{
switch(JoystickType)
{
	/* Tests that if an event occured */
	#define EVENTJS(I)      ( js.rgbButtons[I-1] != previous_js.rgbButtons[I-1] )
	#define TESTJS(I)       ( js.rgbButtons[I-1] & 0x80 ) 
	#define SETJS(I,J)      if( js.rgbButtons[I-1] & 0x80 )  J(1); else J(0);
	
	/********************/

case GAMEPAD_PLAYSTATION3:

	pitch = js.lY/(1000.0f) /* belongs to [-1000:1000] */;
	roll  = js.lX/(1000.0f) /* belongs to [-1000:1000] */;
	yaw   = js.lZ/(1000.0f) /* belongs to [-1000:1000] */;
	gaz   = js.lRz/(1000.0f) /* belongs to [-1000:1000] */;

		
	// Buttons hard coded for the Playstation3 SixAxis pad connected in USB mode on a Windows XP computer
		if (EVENTJS(9)) {
		if (TESTJS(9))  
			{ 
				ardrone_tool_set_ui_pad_start(0); 
				ardrone_tool_set_ui_pad_select(1);  
				printf("Sending emergency.%s\n",linefiller); 
			}
		else
			{
					ardrone_tool_set_ui_pad_select(0);  
			}
		}

		if (EVENTJS(10) && TESTJS(10)) 
		{ 
			start^=1; 
			ardrone_tool_set_ui_pad_start(start);  
			printf("Sending start %i.%s\n",start,linefiller); 
		}
	
	break;


	/********************/

case JOYSTICK_CYBORG_X:

	pitch = js.lY/(1000.0f) /* belongs to [-1000:1000] */;
	roll  = js.lX/(1000.0f) /* belongs to [-1000:1000] */;
	yaw   = js.lRz/(1000.0f) /* belongs to [-1000:1000] */;

	/* From MSDN :
	Direction controllers, such as point-of-view hats. 
	The position is indicated in hundredths of a degree clockwise from north (away from the user). 
	The center position is normally reported as - 1; but see Remarks. 
	For indicators that have only five positions, the value for a controller is - 1, 0, 9,000, 18,000, or 27,000.
	*/
	switch (js.rgdwPOV[0])
	{
	case 0: gaz = 1.0f; break;
	case 4500: gaz = 0.5f; break;
	case 13500: gaz = -0.5f; break;
	case 18000: gaz = -1.0f; break;
	case 22500: gaz = -0.5f; break;
	case 31500: gaz = +0.5f; break;
	default:gaz = 0.0f; 
	}
	
		
	// Buttons hard coded for the Playstation3 SixAxis pad connected in USB mode on a Windows XP computer
		if (EVENTJS(2)||EVENTJS(3)||EVENTJS(4)||EVENTJS(5)) {
		if (TESTJS(2)||TESTJS(3)||TESTJS(4)||TESTJS(5))  
			{ 
				ardrone_tool_set_ui_pad_start(0); 
				ardrone_tool_set_ui_pad_select(1);  
				printf("Sending emergency.%s\n",linefiller); 
			}
		else
			{
					ardrone_tool_set_ui_pad_select(0);  
			}
		}

		if (EVENTJS(1) && TESTJS(1)) 
		{ 
			start^=1; 
			ardrone_tool_set_ui_pad_start(start);  
			printf("Sending start %i.%s\n",start,linefiller); 
		}
	
	break;
	/********************/
	
case GAMEPAD_LOGITECH_PRECISION:
	

	pitch = (float)js.lY/(1000.0f);
	roll  = (float)js.lX/(1000.0f);
	
	yaw   = (TESTJS(3))? (1.0f) : (TESTJS(1))? (-1.0f) : (0.0f) ;
	gaz   = (TESTJS(4))? (1.0f) : (TESTJS(2))? (-1.0f) : (0.0f) ;

	if (EVENTJS(9)) {
		if (TESTJS(9))  
			{ 
				ardrone_tool_set_ui_pad_start(0); 
				ardrone_tool_set_ui_pad_select(1);  
				printf("Sending emergency.%s\n",linefiller); 
			}
		else
			{
					ardrone_tool_set_ui_pad_select(0);  
			}
	}

	if (EVENTJS(10) && TESTJS(10)) 
		{ 
			start^=1; 
			ardrone_tool_set_ui_pad_start(start);  
			printf("Sending start %i.%s\n",start,linefiller); 
		}
	
	if (EVENTJS(5) &&  TESTJS(5))  
		{
			ardrone_at_set_flat_trim(); 
			printf("Sending flat trim.%s\n",linefiller); 
		}
		
	break;

/********************/
	
case GAMEPAD_RADIO_GP:

	pitch = (float)js.lZ/(1000.0f);
	roll  = (float)js.lRz/(1000.0f);
	
	yaw   = (float)js.lX/(1000.0f);
	gaz   = -(float)js.lY/(1000.0f);
	
	
	if (EVENTJS(2)) {
		if (TESTJS(2))  
			{ 
				ardrone_tool_set_ui_pad_start(0); 
				ardrone_tool_set_ui_pad_select(1);  
				printf("Sending flat trim.%s\n",linefiller); 
				ardrone_at_set_flat_trim(); 
			}
	}

	if (EVENTJS(3)) {
		if (TESTJS(3))  
			{ 
				ardrone_tool_set_ui_pad_start(0); 
				ardrone_tool_set_ui_pad_select(1);  
				printf("Sending emergency.%s\n",linefiller); 
			}
		else
			{
					ardrone_tool_set_ui_pad_select(0);  
			}
	}

	if (EVENTJS(1)) 
		{ 
			start= TESTJS(1)?1:0; // button 1 is an on/off switch that does not need to be maintained
			ardrone_tool_set_ui_pad_start(start);  
			printf("Sending start %i.%s\n",start,linefiller); 
		}
	
	
	
	break;
default: 
	pitch=roll=gaz=yaw=0.0f;

/********************/
} // switch 
} // keyboardinuse

	if(!keyboard_in_use)
	{
		ardrone_tool_set_pcmd(1,roll, pitch, gaz, yaw, 0.0, 0.0);
	
		printf("[Pitch %f] [Roll %f] [Yaw %f] [Gaz %f]%\n",pitch,roll,yaw,gaz);
	}

	/* Keeps track of the last joystick state in a static variable */
	previous_js=js;
	

 ARWin32Demo_ReleaseConsole();
 return C_OK;
}
C_RESULT ardrone_academy_navdata_process( const navdata_unpacked_t* const pnd )
{
  static bool_t prevCameraIsReady = FALSE;
    static bool_t prevDroneUsbRecording = FALSE;
  if (C_OK == TRYLOCK_ND_MUTEX ())
    {
      input_state_t* input_state = ardrone_tool_input_get_state();
        bool_t recordIsReady = ! ardrone_academy_navdata_get_record_ready();
        bool_t recordIsInProgress = ardrone_academy_navdata_get_record_state();

        // Save ARDrone State
        navdata_state.lastState = pnd->ardrone_state;

        // Save remaining USB time
        navdata_state.usbFreeTime = pnd->navdata_hdvideo_stream.usbkey_remaining_time;

        bool_t currentDroneUsbRecording = (NAVDATA_HDVIDEO_USBKEY_IS_RECORDING == (NAVDATA_HDVIDEO_USBKEY_IS_RECORDING & pnd->navdata_hdvideo_stream.hdvideo_state));
        // Check for record stop from drone
        if (navdata_state.usbRecordInProgress)
        {
            if (TRUE  == prevDroneUsbRecording &&
                FALSE == currentDroneUsbRecording)
            {
                navdata_state.droneStoppedUsbRecording = TRUE;
                navdata_state.record_state = RECORD_STATE_NEEDED;
            }
        }
        prevDroneUsbRecording = currentDroneUsbRecording;

      ardrone_academy_check_take_off_timeout ();

      // Take off and Emergency management
      if(navdata_state.takeoff_state == TAKEOFF_STATE_NEEDED)
	{
          if(pnd->ardrone_state & ARDRONE_EMERGENCY_MASK)
            {
              navdata_state.needSetEmergency = TRUE;
            }
          else
            {
                if(recordIsInProgress)
                {
                  if(!(pnd->ardrone_state & ARDRONE_USER_FEEDBACK_START))
                    ardrone_tool_set_ui_pad_start(1);
                  else
                    ardrone_tool_set_ui_pad_start(0);
                  navdata_state.takeoff_state = TAKEOFF_STATE_IDLE;

                }
              else
                {
                  navdata_state.takeoff_state = TAKEOFF_STATE_WAIT_USERBOX;
                  ardrone_academy_navdata_userbox_switch();
                }
            }
	}

      if(navdata_state.needSetEmergency)
	{
          ardrone_tool_set_ui_pad_select(1);
          navdata_state.needSetEmergency = FALSE;
	}

      if(pnd->ardrone_state & ARDRONE_EMERGENCY_MASK)
        {
          if(!navdata_state.wasEmergency && (input_state->user_input & (1 << ARDRONE_UI_BIT_SELECT)))
            {
              ardrone_tool_set_ui_pad_select(0);
            }
        
          navdata_state.isEmergency = TRUE;
          navdata_state.isTakeOff = FALSE;

            if(!navdata_state.internalRecordInProgress && !navdata_state.usbRecordInProgress && (navdata_state.userbox_state == USERBOX_STATE_STARTED))
            {
                PRINT("Emergency !! Stopping userbox...\n");
              ardrone_academy_navdata_userbox_switch();
            }

          ardrone_tool_input_start_reset();
        }
      else // Not emergency landing
        {
          if(navdata_state.wasEmergency && (input_state->user_input & (1 << ARDRONE_UI_BIT_SELECT)))
            {
              ardrone_tool_set_ui_pad_select(0);
            }
        
          if(!(pnd->ardrone_state & ARDRONE_TIMER_ELAPSED))
            navdata_state.isEmergency = FALSE;

          if(input_state->user_input & (1 << ARDRONE_UI_BIT_START))
            {
              navdata_state.isTakeOff = (pnd->ardrone_state & ARDRONE_USER_FEEDBACK_START) ? TRUE : FALSE;
            }
          else
            {
              navdata_state.isTakeOff = FALSE;
            }
        }
      navdata_state.wasEmergency = (pnd->ardrone_state & ARDRONE_EMERGENCY_MASK) ? TRUE : FALSE;
    
      // Video record management

        bool_t usbRecordEnable = FALSE;
        if(navdata_state.record_state == RECORD_STATE_NEEDED &&
           TAKEOFF_STATE_IDLE == navdata_state.takeoff_state)
        {
            bool_t continueRecord = TRUE;
            bool_t nextInternalRecordState = FALSE;
            if (IS_LEAST_ARDRONE2)
	{
          static codec_type_t oldCodec;
                codec_type_t cancelCodec;
                if (recordIsReady && ! navdata_state.usbRecordInProgress && !navdata_state.internalRecordInProgress) // We want to enable recording
            {
                if ((ARDRONE_USB_MASK == (pnd->ardrone_state & ARDRONE_USB_MASK)) &&
                        (0 < pnd->navdata_hdvideo_stream.usbkey_remaining_time) &&
                    (TRUE == ardrone_control_config.video_on_usb))
                {
                        usbRecordEnable = TRUE;
                }
                    // Set the "non-record codec" to the codec defined as the application default
                    oldCodec = ardrone_application_default_config.video_codec;
                    cancelCodec = oldCodec;
                    ardrone_control_config.video_codec = (TRUE == usbRecordEnable) ? usbRecordCodec : deviceWifiRecordCodec;
                    PRINT ("Set codec %d -> %d\n", oldCodec, ardrone_control_config.video_codec);
                    nextInternalRecordState = TRUE;
            }
          else // We want to disable recording
            {
                    cancelCodec = ardrone_control_config.video_codec;
              ardrone_control_config.video_codec = oldCodec;
                    PRINT ("Reset codec %d -> %d\n", cancelCodec, oldCodec);
            }
                bool_t addEventSucceeded = ARDRONE_TOOL_CONFIGURATION_ADDEVENT (video_codec, &ardrone_control_config.video_codec, NULL);
                if (FALSE == addEventSucceeded)
                {
                    PRINT ("Unable to send codec switch ... retry later\n");
                    ardrone_control_config.video_codec = cancelCodec;
                    continueRecord = FALSE;
                }
            }
            else if (IS_ARDRONE1)
            {
                nextInternalRecordState = !recordIsInProgress;
            }

            if (TRUE == continueRecord)
            {
                navdata_state.internalRecordInProgress = nextInternalRecordState;
            switch (navdata_state.userbox_state)
            {
            case USERBOX_STATE_STOPPED:
              navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
                    navdata_state.usbRecordInProgress = usbRecordEnable;
              ardrone_academy_navdata_userbox_switch();
                break;
            case USERBOX_STATE_STARTED:
              if(navdata_state.isTakeOff)
                {
                        if(! recordIsReady)
                    {
                            PRINT("Userbox is started and record is started => Stop record\n");
                      ardrone_academy_navdata_recorder_enable(FALSE, navdata_state.userbox_time);
                      navdata_state.usbRecordInProgress = FALSE;
                    }
                  else
                    {
                            PRINT("Userbox is started and record is stopped => Start record\n");
                            if (FALSE == usbRecordEnable)
                        {
                            // Only activate the local recorder if we don't record on USB
                      ardrone_academy_navdata_recorder_enable(TRUE, navdata_state.userbox_time);
                                navdata_state.usbRecordInProgress = FALSE;
                            }
                            else
                            {
                                navdata_state.usbRecordInProgress = TRUE;
                        }
                    }

                  navdata_state.record_state = RECORD_STATE_IDLE;
                }
              else
                {
                  navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
                  ardrone_academy_navdata_userbox_switch();
                }
                break;
            case USERBOX_STATE_STARTING:
                    navdata_state.usbRecordInProgress = usbRecordEnable;
                navdata_state.record_state = RECORD_STATE_WAIT_USERBOX;
                break;
            case USERBOX_STATE_STOPPING:
                    navdata_state.usbRecordInProgress = usbRecordEnable;
                // Should never be here
                PRINT ("Don't know what to do for USERBOX_STATE_STOPPING\n");
                VP_OS_ASSERT (0 == 1); // Debug handler
                break;
                }
            }
        }

      // Screenshot management
      prevCameraIsReady = navdata_state.cameraIsReady;
      navdata_state.cameraIsReady = (pnd->ardrone_state & ARDRONE_CAMERA_MASK) ? TRUE : FALSE;
      if (TRUE == navdata_state.cameraIsReady && FALSE == prevCameraIsReady)
      {
          academy_download_resume ();
      }
        
      if((navdata_state.screenshot_state == SCREENSHOT_STATE_NEEDED) && navdata_state.cameraIsReady)
      {
          static char param[ARDRONE_DATE_MAXSIZE + 64];
          static char date[ARDRONE_DATE_MAXSIZE];
          time_t t = time(NULL);
          ardrone_time2date(t, ARDRONE_FILE_DATE_FORMAT, date);
          navdata_state.screenshot_state = SCREENSHOT_STATE_INPROGRESS;
          sprintf(param, "%d,%d,%d,%s", USERBOX_CMD_SCREENSHOT, 0, 0, date);
          ARDRONE_TOOL_CONFIGURATION_ADDEVENT(userbox_cmd, param, ardrone_academy_navdata_screenshot_cb);
      }

      // USB management
      navdata_state.usbIsReady = (pnd->ardrone_state & ARDRONE_USB_MASK) ? TRUE : FALSE;
      UNLOCK_ND_MUTEX ();
    }
  return C_OK;
}
示例#9
0
C_RESULT update_dx_keyboard(void)
{
	static float roll = 0, pitch = 0, gaz=0, yaw=0;
	static int hovering=0;

	const char * linefiller="                                              ";

	

/* Direct Input keyboard state */
		char keyboardState[256];
		static char previous_keyboardState[256];

		static bool function_first_call = true;

		// Get the keyboard state
		hr = fDIKeyboard->GetDeviceState( sizeof(keyboardState),
										(LPVOID)&keyboardState	);
		if (FAILED(hr))	fDIKeyboard->Acquire();



	if (function_first_call) { 
		printf("Sending flat trim - make sure the drone is horizontal at client startup.\n"); 
		ardrone_at_set_flat_trim();
		function_first_call=false; 
		vp_os_memcpy(previous_keyboardState,keyboardState,sizeof(keyboardState));
		return C_OK; 
		
	}

	ARWin32Demo_AcquireConsole();
	ARWin32Demo_SetConsoleCursor(0,12);

		// Process the keyboard data

	#define EVENTKB(I)      ( keyboardState[I] != previous_keyboardState[I] )
	#define TESTKB(I)       ( keyboardState[I] & 0x80 ) 
	#define SETKB(I,J)      if( keyboardState[I] & 0x80 )  J(1); else J(0);

	pitch = (TESTKB(DIK_NUMPAD2))? (+1.0f) : (TESTKB(DIK_NUMPAD8))? (-1.0f) :
			(TESTKB(DIK_K))? (+1.0f)       : (TESTKB(DIK_I))? (-1.0f)			:(0.0f) ;
	roll  = (TESTKB(DIK_NUMPAD4))? (-1.0f) : (TESTKB(DIK_NUMPAD6))? (+1.0f) :
			(TESTKB(DIK_J))? (-1.0f)       : (TESTKB(DIK_L))? (+1.0f)		: (0.0f) ;
	yaw   = (TESTKB(DIK_NUMPAD7))? (-1.0f) : (TESTKB(DIK_NUMPAD9))? (+1.0f) : 
			(TESTKB(DIK_NUMPAD3))? (-1.0f) : (TESTKB(DIK_NUMPAD1))? (+1.0f) :
			(TESTKB(DIK_U))? (-1.0f)       : (TESTKB(DIK_O))? (+1.0f) :  (0.0f) ;
	gaz   = (TESTKB(DIK_A))? (-1.0f)       : (TESTKB(DIK_Q))?      (1.0f) : (0.0f) ;
	hovering = (TESTKB(DIK_G))? (1):(0) ;

	keyboard_in_use = !((pitch+roll+gaz+yaw)==0);
	


	if (EVENTKB(DIK_ESCAPE)) {
		if (TESTKB(DIK_ESCAPE))  
			{
				exit_ihm_program=0;
			}
	}

	if (EVENTKB(DIK_TAB)) {
		if (TESTKB(DIK_TAB))  
			{ 
				ardrone_tool_set_ui_pad_start(0); 
				ardrone_tool_set_ui_pad_select(1);  
				printf("Sending emergency.%s\n",linefiller); 
			}
		else
			{
					ardrone_tool_set_ui_pad_select(0);  
			}
	}

	if (EVENTKB(DIK_SPACE) && TESTKB(DIK_SPACE)) 
		{ 
			start^=1; 
			ardrone_tool_set_ui_pad_start(start);  
			printf("Sending start %i.%s\n",start,linefiller); 
		}
	
	if (EVENTKB(DIK_F) &&  TESTKB(DIK_F))  
		{
			ardrone_at_set_flat_trim(); 
			printf("Sending flat trim.%s\n",linefiller); 
		}


	ardrone_tool_set_pcmd((hovering)?0:1,roll, pitch, gaz, yaw,0.0,0.0);
	printf("[Pitch %f] [Roll %f] [Yaw %f] [Gaz %f]%\n",pitch,roll,yaw,gaz);

	vp_os_memcpy(previous_keyboardState,keyboardState,sizeof(keyboardState));

	ARWin32Demo_ReleaseConsole();

	return C_OK;
}
示例#10
0
C_RESULT update_wiimote(void)
{
  C_RESULT res = C_OK;
  static struct cwiid_state state,previous_state;

  static int control_mode = 1;
  static int valid_domain = 0;

  int8_t x, y;
  static int start=0;
  static int select=0;

  static vec3 a={0,0,0},s={0,0,0};
  static vec3sph r={0,0,0},pr={0,0,0},rref={0,0,0};

  static float pitch=0.0f,roll=0.0f,gaz=0.0f,yaw=0.0f;

  float tmp;
  static int fly=0;



  if (cwiid_get_state(wiimote, &state))
    {
      fprintf(stderr, "Error getting state\n");
      res = C_FAIL;
    }


#define SWITCHING(X) ((state.buttons&X) && !(previous_state.buttons&X))
#define RELEASING(X) ((!state.buttons&X) && (previous_state.buttons&X))
#define PRESSED(X) ((state.buttons&X))
  static int flag_rumble=0;
#define RUMBLE_ON { if (!flag_rumble) {flag_rumble=1;  } }
  /* Sets how to use the wiimote */
#define MAXMODE 4
  if (SWITCHING(CWIID_BTN_MINUS)) {
	  control_mode--;
	  if (control_mode<1) control_mode=MAXMODE;
	  leds(1<<(control_mode-1));
  }
  if (SWITCHING(CWIID_BTN_PLUS))  {
	  control_mode++;
	  if (control_mode>MAXMODE) control_mode=1;
	  leds(1<<(control_mode-1));
  }

 /* Gets gravitation G projection on x,y,z axis */
	  a.x = - (float32_t) ((((double)state.acc[CWIID_X] - wm_cal.zero[CWIID_X]) /
				  (wm_cal.one[CWIID_X] - wm_cal.zero[CWIID_X])));
	  a.y = - (float32_t) ((((double)state.acc[CWIID_Y] - wm_cal.zero[CWIID_Y]) /
				  (wm_cal.one[CWIID_Y] - wm_cal.zero[CWIID_Y])));
	  a.z = + (float32_t) ((((double)state.acc[CWIID_Z] - wm_cal.zero[CWIID_Z]) /
			  (wm_cal.one[CWIID_Z] - wm_cal.zero[CWIID_Z])));

	  s.x = (a.x<0.0f)?(1.0f):(-1.0f);
	  s.y = (a.y<0.0f)?(1.0f):(-1.0f);
	  s.z = (a.z<0.0f)?(1.0f):(-1.0f);

	  float ax2 = a.x*a.x;
	  float ay2 = a.y*a.y;
	  float az2 = a.z*a.z;

	  r.r = sqrtf((ax2+ay2)+az2);

	  switch(control_mode)
	  {
	  case 1:
	  case 2:

	  	  if (r.r==0.0f) { r.p=r.t=0.0f; } else {
	  		  // Angle gauche/droite
	  		  r.p = asin(a.y);  if (isnan(r.p)) r.p=0.0f;

			  // Sur plan vertical radial
				  r.t = acos(a.z/(sqrtf(az2+ax2)));  if (isnan(r.t)) r.t=0.0f;
				  r.t*=s.x;
	  	  }
	  	  break;

	  case 3:
	  case 4:

	  	  	  if (r.r==0.0f) { r.p=r.t=0.0f; } else {
	  	  		  // Angle entre le projete de G sur le plan vertical longitudinal (yz) et l'axe z
	  				  r.p = acos(a.z/(sqrtf(az2+ay2)));  if (isnan(r.p)) r.p=0.0f;
	  				  /* If wiimote faces the ground */
	  				    //if (a.z<0.0f) r.p= M_PI-r.p;
	  				  r.p*=s.y;
	  			  // Idem sur le plan vertical radial
	  				  r.t = acos(a.z/(sqrtf(az2+ax2)));  if (isnan(r.t)) r.t=0.0f;
	  				  r.t*=s.x;
	  	  	  }
	  	  	  break;
	    }

	  r.r = (r.r+pr.r)/2.0f;
	  r.t = (r.t+pr.t)/2.0f;
	  r.p = (r.p+pr.p)/2.0f;



  switch(control_mode)
  {

		  case 1:
		  case 2:
			  /* Wiimote is handled horizontally.
			   * '2' button under left thumb
			   * directionnal cross under right thumb
			   */


			  /* 0 -> buttons facing sky */

			  if ((SWITCHING(CWIID_BTN_1)||SWITCHING(CWIID_BTN_2)||SWITCHING(CWIID_BTN_B))){  rref=r;  }

			  if (PRESSED(CWIID_BTN_1)||PRESSED(CWIID_BTN_2)||PRESSED(CWIID_BTN_B))
			  {
				  /* If wiimote facing ground */
				  if (a.z<0 && a.x>0)
				  {
					  rumble(1);
				  }
				  else
				  {
					  rumble(0);
					  leds(1<<(control_mode-1));
					  pitch = (r.t-rref.t)*1.0f; if (pitch<-1.0f) pitch=-1.0f; if (pitch>1.0f) pitch=1.0f;
					  roll  = -(r.p-rref.p)*0.75f; if (roll<-1.0f)  roll=-1.0f; if (roll>1.0f) roll=1.0f;
					  fly=1;
				  }
			  }
			  else
			  {
				  pitch=roll=0;
				  rumble(0);
				  leds(1<<(control_mode-1));
				  fly=0;
			  }


			  gaz  = (PRESSED(CWIID_BTN_LEFT))? 1.0f: (PRESSED(CWIID_BTN_RIGHT)) ? -1.0f : 0.0f;
			  yaw  = (PRESSED(CWIID_BTN_DOWN))? -1.0f: (PRESSED(CWIID_BTN_UP))   ? 1.0f : (control_mode==2) ? (-pitch*roll) : 0.0f;

			  break;


		  case 3:
		  case 4:

			  if (PRESSED(CWIID_BTN_B))
 			  {
				  if (a.z<-0.5f)
				  {
					  rumble(1);
				  }
				  else
				  {
					  rumble(0);
					  leds(1<<(control_mode-1));
					  pitch = -(r.p-rref.p)*1.5f; if (pitch<-1.0f) pitch=-1.0f; if (pitch>1.0f) pitch=1.0f;
					  roll  = (r.t-rref.t)*1.5f; if (roll<-1.0f)  roll=-1.0f; if (roll>1.0f) roll=1.0f;
					  fly=1;
				  }
			  }
			  else
				  {
				  	 rumble(0);
				     leds(1<<(control_mode-1));
				  	 fly=0;
				  	 pitch=roll=0;

				  }

			  if (SWITCHING(CWIID_BTN_B))  { rref = r; }

			  gaz  = (PRESSED(CWIID_BTN_DOWN))? -1.0f: (PRESSED(CWIID_BTN_UP)) ? +1.0f : 0.0f;
			  yaw  = (PRESSED(CWIID_BTN_LEFT))? -1.0f: (PRESSED(CWIID_BTN_RIGHT))   ? 1.0f : (control_mode==4) ? (-pitch*roll) : 0.0f;

  }
  /* Buttons common to all modes */
  	  if (SWITCHING(CWIID_BTN_A)) { start^=1;  ardrone_tool_set_ui_pad_start(start); }
  	  if (SWITCHING(CWIID_BTN_HOME)) {
  				  				  select^=1;
  				  				  ardrone_tool_set_ui_pad_select(select);
  				  				  ardrone_tool_set_ui_pad_start(0);
  				  			  }


	  //
	//printf("Wiimote mode 2 [ax %f][ay %f][az %f]\n\033[1A", a.x,a.y,a.z);
  	printf("Wiimode %i  [rr %3.2f][rp %3.2f][rt %3.2f]\n", control_mode,r.r,r.p,r.t);
  	printf("[Fly %i][Ptc %3.2f][Rl %3.2f][Yw %3.2f][Gz %3.2f][Strt. %i][Sel. %i]\n\033[2A", fly,pitch,roll,yaw,gaz,start,select);
	  ardrone_at_set_progress_cmd( fly,/*roll*/roll,/*pitch*/pitch,/*gaz*/gaz,/*yaw*/yaw);

  /*api_set_iphone_acceleros(
			   (state.buttons&CWIID_BTN_2 ? 1 : 0)|(state.buttons&CWIID_BTN_A ? 2 : 0),
			   a_x, a_y, a_z);*/

  previous_state = state;
  pr=r;

  return C_OK;
}
示例#11
0
void checkErrors(void)
{
	input_state_t* input_state = ardrone_tool_get_input_state();
	
	strcpy(ctrldata.error_msg, "");
	
	if(!ctrldata.wifiReachabled)
	{
		strcat(ctrldata.error_msg, messages[MESSAGEBOX_WIFI_NOT_REACHABLED]);
		strcat(ctrldata.error_msg, "\n");
		resetControlData();
	}
	else
	{
		if(ctrldata.needAnimation >= 0)
		{
			ardrone_at_set_anim(ctrldata.needAnimation, MAYDAY_TIMEOUT[ctrldata.needAnimation]);
			ctrldata.needAnimation = -1;
		}
		
		if(ctrldata.needVideoSwitch >= 0)
		{
			ardrone_at_zap(ctrldata.needVideoSwitch);
			ctrldata.needVideoSwitch = -1;
		}
		
		if(ctrldata.needChangeCameraDetection >= 0)
		{
			ardrone_at_cad(ctrldata.needChangeCameraDetection, ctrldata.tag_size);
			ctrldata.needChangeCameraDetection = -1;
		}	
		
		if(ctrldata.needLedAnimation >= 0)
		{
			ardrone_at_set_led_animation(ctrldata.needLedAnimation, ctrldata.ledAnimFreq, ctrldata.ledAnimDuration);
			ctrldata.needLedAnimation = -1;
		}	
		
		if(ctrldata.needSetEmergency)
		{
			ctrldata.isInEmergency = ctrlnavdata.emergencyLanding;
			ardrone_tool_set_ui_pad_select(1);
			ctrldata.needSetEmergency = FALSE;
		}
		
		if( ctrldata.needSetNavdataDemo)
		{
			if( control_ack_configure_navdata_demo(ctrldata.navdata_demo))
				ctrldata.needSetNavdataDemo = FALSE;
		}
		else if( ctrldata.needSetPairing )
		{
			if(control_ack_configure_mac_address((const char*)&iphone_mac_address[0]))
				ctrldata.needSetPairing = FALSE;
		}
		else if(ctrldata.needSetFrequency)
		{
			if(control_ack_configure_ultrasound_frequency(!ctrldata.is_client))
				ctrldata.needSetFrequency = FALSE;
		}
		else if(ctrldata.needSetManualTrim)
		{
			if(control_ack_configure_manual_trim(ctrldata.manual_trim))
			{
				ctrldata.needSetManualTrim = FALSE;
				ctrldata.manual_trim_enabled = ctrldata.manual_trim;
			}
		}
		else if(ctrldata.needGetConfiguration)
		{
			//PRINT("Request configuration file\n");
			if(control_get_configuration())
				ctrldata.needGetConfiguration = FALSE;
		}
		
		if((ctrldata.framecounter % (kFPS / 2)) == 0)
		{
			if(ctrlnavdata.bootstrap)
			{
				setNavdataDemo(TRUE);
				ctrldata.needSetFrequency = TRUE;
				ctrldata.needGetConfiguration = TRUE;
				ctrldata.needSetPairing = TRUE;
			}
		}
		
		if(ardrone_navdata_client_get_num_retries() >= NAVDATA_MAX_RETRIES)
		{
			strcat(ctrldata.error_msg, messages[MESSAGEBOX_CANT_CONNECT_TO_TOY]);
			strcat(ctrldata.error_msg, "\n");
			resetControlData();
		}
		else if(ctrlnavdata.emergencyLanding)
		{
			if(!ctrldata.isInEmergency && input_state->select)
				ardrone_tool_set_ui_pad_select(0);
			
			strcpy(ctrldata.emergency_msg, "reset");
			strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_PRESS_RESET]);
			strcat(ctrldata.error_msg, "\n");
			
			if(ctrlnavdata.ultrasoundProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_ULTRASOUND]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.cutoutProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_CUT_OUT]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.motorsProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_MOTORS]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.cameraProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_CAMERA]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.adcProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_PIC_WATCHDOG]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.adcVersionProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_PIC_VERSION]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.anglesProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_TOO_MUCH_ANGLE]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.vbatLowProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_BATTERY_LOW]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.userEmergency)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_USER]);
				strcat(ctrldata.error_msg, "\n");
			}
			else
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_EMERGENCY_UNKNOWN]);
				strcat(ctrldata.error_msg, "\n");
			}
						
			resetControlData();
			ardrone_tool_start_reset();

			if(ctrlnavdata.startPressed)
				switchTakeOff();
		}
		else if(!ctrlnavdata.emergencyLanding)
		{	
			if(ctrldata.isInEmergency && input_state->select)
				ardrone_tool_set_ui_pad_select(0);
			
			if(video_stage_get_num_retries() > VIDEO_MAX_RETRIES)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_ALERT_NO_VIDEO_CONNECTION]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.vbatLowProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_ALERT_BATTERY_LOW]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.ultrasoundProblem)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_ALERT_ULTRASOUND]);
				strcat(ctrldata.error_msg, "\n");
			}
			else if(ctrlnavdata.visionProblem && ctrlnavdata.flyingState)
			{
				strcat(ctrldata.error_msg, messages[MESSAGEBOX_ALERT_VISION]);
				strcat(ctrldata.error_msg, "\n");
			}

			if(!ctrlnavdata.timerElapsed)
				strcpy(ctrldata.emergency_msg, "emergency");
			
			if(input_state->start)
			{
				if(ctrlnavdata.startPressed)
				{
					strcpy(ctrldata.takeoff_msg, "take_land");
				}
				else
				{	
					strcpy(ctrldata.takeoff_msg, "take_off");
					strcat(ctrldata.error_msg, messages[MESSAGEBOX_START_NOT_RECEIVED]);
					strcat(ctrldata.error_msg, "\n");
				}
			}
			else
			{
				strcpy(ctrldata.takeoff_msg, "take_off");
			}			
		}
		
	}
}
示例#12
0
C_RESULT update_gamepad(void)
{
  static int32_t x = 0, y = 0;
  static bool_t refresh_values = FALSE;
  ssize_t res;
  static struct js_event js_e_buffer[64];
  static int32_t start = 0;
  input_state_t* input_state;

  static int32_t theta_trim = 0;
  static int32_t phi_trim   = 0;
  static int32_t yaw_trim   = 0;


  res = read(joy_dev, js_e_buffer, sizeof(struct js_event) * 64);

  if( !res || (res < 0 && errno == EAGAIN) )
    return C_OK;

  if( res < 0 )
    return C_FAIL;

  if (res < (int) sizeof(struct js_event))// If non-complete bloc: ignored
    return C_OK;

  // Buffer decomposition in blocs (if the last is incomplete, it's ignored)
  int32_t idx = 0;
  refresh_values = FALSE;
  input_state = ardrone_tool_get_input_state();
  for (idx = 0; idx < res / sizeof(struct js_event); idx++)
  {
    if(js_e_buffer[idx].type & JS_EVENT_INIT )// If Init, the first values are ignored
    {
      break;
    }
    else if(js_e_buffer[idx].type & JS_EVENT_BUTTON )// Event Button detected
    {
      switch( js_e_buffer[idx].number )
      {
        case PAD_AG :
		ardrone_tool_set_ui_pad_ag(js_e_buffer[idx].value);
		break;
        case PAD_AB :
		ardrone_tool_set_ui_pad_ab(js_e_buffer[idx].value);
		break;
        case PAD_AD :
		ardrone_tool_set_ui_pad_ad(js_e_buffer[idx].value);
		break;
        case PAD_AH :
		ardrone_tool_set_ui_pad_ah(js_e_buffer[idx].value);
		break;
        case PAD_L1 :
		if( js_e_buffer[idx].value )
		{
			yaw_trim = 0;

			if( input_state->r2 )
			{
				yaw_trim = -1;
			}
			else
			{
				ardrone_tool_set_ui_pad_l1(1);
			}
        // ui_pad_yaw_trim( yaw_trim );
		}
      else
      {
         yaw_trim = 0;
         ardrone_tool_set_ui_pad_l1(0);
       //  ui_pad_yaw_trim( yaw_trim );
      }
		break;
        case PAD_R1 :
		if( js_e_buffer[idx].value )
		{
			yaw_trim = 0;

			if( input_state->r2 )
			{
				yaw_trim = 1;
			}
			else
			{
				ardrone_tool_set_ui_pad_r1(1);
			}
        // ui_pad_yaw_trim( yaw_trim );
		}
      else
      {
         yaw_trim = 0;
         ardrone_tool_set_ui_pad_r1(0);
        // ui_pad_yaw_trim( yaw_trim );
      }
		break;
        case PAD_L2 :
		ardrone_tool_set_ui_pad_l2(js_e_buffer[idx].value);
		if( !js_e_buffer[idx].value )
		{
			ardrone_at_set_pmode( MiscVar[0] );
			ardrone_at_set_ui_misc( MiscVar[0], MiscVar[1], MiscVar[2], MiscVar[3] );
		}
		break;
        case PAD_R2 :
		ardrone_tool_set_ui_pad_r2(js_e_buffer[idx].value);
      if( !js_e_buffer[idx].value )
         ardrone_at_set_flat_trim();
		break;
        case PAD_SELECT :
		ardrone_tool_set_ui_pad_select(js_e_buffer[idx].value);
		break;
        case PAD_START :
      if( js_e_buffer[idx].value )
      {
         start ^= 1;
		   ardrone_tool_set_ui_pad_start( start );
		}
      break;
        default:
		break;
      }

    }
    else if(js_e_buffer[idx].type & JS_EVENT_AXIS )// Event Axis detected
    {
      refresh_values = TRUE;
      switch( js_e_buffer[idx].number )
      {
        case PAD_X:
          x = ( js_e_buffer[idx].value + 1 ) >> 15;
          break;
        case PAD_Y:
          y = ( js_e_buffer[idx].value + 1 ) >> 15;
          break;
        default:
          break;
      }
    }
    else
    {// TODO: default: ERROR (non-supported)
    }
  }

  if(refresh_values)// Axis values to refresh
C_RESULT update_teleop(void)
{
	// This function *toggles* the emergency state, so we only want to toggle the emergency
	// state when we are in the emergency state (because we want to get out of it).
    vp_os_mutex_lock(&twist_lock);
    if (needs_reset)
    {
        ardrone_tool_set_ui_pad_select(1);
        needs_reset = false;
    }
    else if (needs_takeoff)
    {
        ardrone_tool_set_ui_pad_start(1);
        needs_takeoff = false;
    }
    else if (needs_land)
    {
        ardrone_tool_set_ui_pad_start(0);
        needs_land = false;
    }
    else
    {

        float left_right = (float) cmd_vel.linear.y;
        float front_back = (float) cmd_vel.linear.x;
        float up_down = (float) cmd_vel.linear.z;
        float turn = (float) cmd_vel.angular.z;
        
        bool is_changed = !(
                (fabs(left_right - old_left_right) < _EPS) && 
                (fabs(front_back - old_front_back) < _EPS) && 
                (fabs(up_down - old_up_down) < _EPS) && 
                (fabs(turn - old_turn) < _EPS)
                );
        
        // These lines are for testing, they should be moved to configurations
        // Bit 0 of control_flag == 0: should we hover?
        // Bit 1 of control_flag == 1: should we use combined yaw mode?
        
        int32_t control_flag = 0x00;
        int32_t combined_yaw = 0x00;
        
        // Auto hover detection based on ~0 values for 4DOF cmd_vel
        int32_t hover = (int32_t)
                (
                (fabs(left_right) < _EPS) && 
                (fabs(front_back) < _EPS) && 
                (fabs(up_down) < _EPS) && 
                (fabs(turn) < _EPS) &&
                // Set angular.x or angular.y to a non-zero value to disable entering hover
                // even when 4DOF control command is ~0
                (fabs(cmd_vel.angular.x) < _EPS) &&
                (fabs(cmd_vel.angular.y) < _EPS)
                );

        control_flag |= ((1 - hover) << 0);
        control_flag |= (combined_yaw << 1);
        //ROS_INFO (">>> Control Flag: %d", control_flag);
        
        old_left_right = left_right;
        old_front_back = front_back;
        old_up_down = up_down;
        old_turn = turn;
        //is_changed = true;
        if ((is_changed) || (hover))
        {
            ardrone_tool_set_progressive_cmd(control_flag, left_right, front_back, up_down, turn, 0.0, 0.0);
        }

    }
    vp_os_mutex_unlock(&twist_lock);
	return C_OK;
}
示例#14
0
C_RESULT update_gamepad(void) {

	static int32_t start;
    static float phi = 0, theta = 0, gaz = 0, yaw = 0;
    phi = theta = gaz = yaw = 0.0;
    
	struct js_event js_e_buffer[64];
	ssize_t res = read(joy_dev, js_e_buffer, sizeof(struct js_event) * 64);

	if( !res || (res < 0 && errno == EAGAIN) )
		return C_OK;

	if( res < 0 )
		return C_FAIL;

	if (res < (int) sizeof(struct js_event))// If non-complete bloc: ignored
		return C_OK;

	// Buffer decomposition in blocs (if the last is incomplete, it's ignored)
	bool_t refresh_values = TRUE;
	bool_t enable = FALSE;
	int32_t idx = 0;
	printf("Num events: %d\n", sizeof(struct js_event));
	for (idx = 0; idx < res / sizeof(struct js_event); idx++) {

		unsigned char type = js_e_buffer[idx].type;
		unsigned char number = js_e_buffer[idx].number;
		short value = js_e_buffer[idx].value;

		if (type & JS_EVENT_INIT ) {

			break;
		}
		else if (!value) {

			break;
		}
		else if (type & JS_EVENT_BUTTON ) {
            printf("BUTTON: %d\n", number);
            refresh_values = TRUE;
			switch(number ) {

				case BUTTON_START :
					start ^= 1;
					ardrone_tool_set_ui_pad_start( start );
					g_autopilot = FALSE;
					break;
				case BUTTON_SELECT :
					ardrone_tool_set_ui_pad_select(js_e_buffer[idx].value);
					//g_exit = TRUE;
					return C_OK;
				case BUTTON_ZAP:
					agent_zap();
					break;
			    case BUTTON_GAZ_UP:
			        enable = TRUE;
			        gaz = +1;
			        break;
			    case BUTTON_GAZ_DOWN:
			        enable = TRUE;
    			    printf("GAZ DOWN: %f \n", -1);
			        gaz = -1;
			        break;
			    case BUTTON_YAW_R:
			        enable = TRUE;
			        yaw = +js_e_buffer[idx].value;
			        break;
		        case BUTTON_YAW_L:
		            enable = TRUE;
			        yaw = -js_e_buffer[idx].value;
			        break;
				/*case BUTTON_AUTO:
					if (g_autopilot) {
						refresh_values = TRUE;
					}
					else {
						g_autopilot = TRUE;
					}
					break;*/
			}

		}
		else if (type & JS_EVENT_AXIS ) {
            printf("AXIS: %d\n", number);
			if (number != AXIS_IGNORE3 && number != AXIS_IGNORE4) {
				refresh_values = TRUE;
				enable = TRUE;
				float angle = value / (float)SHRT_MAX;
				printf("ANGLE: %f", angle);
				switch (number) {
					case AXIS_PHI:
						phi = angle;
						break;
					case AXIS_THETA:
						theta = angle;
						break;
					//case AXIS_GAZ:
					//	gaz = angle;
					//	break;
					//case AXIS_YAW:
					//	yaw = angle;
					//	break;
				}
			}
		}

	} // loop over events


	if (refresh_values) {

		g_autopilot = FALSE;
		printf("\nSENDING: %f, %f, %f, %f\n", phi, theta, gaz, yaw);
		ardrone_at_set_progress_cmd(enable, phi, theta, gaz, yaw);
	}

	return C_OK;
}
示例#15
0
void recover_emergency() {
  ardrone_tool_set_ui_pad_select(1);
}
C_RESULT update_teleop(void)
{
	// This function *toggles* the emergency state, so we only want to toggle the emergency
	// state when we are in the emergency state (because we want to get out of it).
    vp_os_mutex_lock(&twist_lock);
    if (needs_reset)
    {
        ardrone_tool_set_ui_pad_select(1);
        needs_reset = false;
    }
    else if (needs_takeoff)
    {
        ardrone_tool_set_ui_pad_start(1);
        needs_takeoff = false;
    }
    else if (needs_land)
    {
        ardrone_tool_set_ui_pad_start(0);
        needs_land = false;
    }
    else
    {

        /*
        float left_right = (float) cmd_vel.linear.y;
        float front_back = (float) cmd_vel.linear.x;
        float up_down = (float) cmd_vel.linear.z;
        float turn = (float) cmd_vel.angular.z;
       */

        finalcmd_vel.linear.x = teleopcmd_vel.twist.linear.x+posecmd_vel.linear.x;
	finalcmd_vel.linear.y = teleopcmd_vel.twist.linear.y+posecmd_vel.linear.y;
        finalcmd_vel.linear.z = teleopcmd_vel.twist.linear.z+posecmd_vel.linear.z;
	finalcmd_vel.angular.z = teleopcmd_vel.twist.angular.z+yawcmd_vel.angular.z;

	float left_right = finalcmd_vel.linear.y;
	float front_back = finalcmd_vel.linear.x;
	float up_down = finalcmd_vel.linear.z;
	float turn = finalcmd_vel.angular.z;


       
        bool is_changed = !(
                (fabs(left_right - old_left_right) < _EPS) && 
                (fabs(front_back - old_front_back) < _EPS) && 
                (fabs(up_down - old_up_down) < _EPS) && 
                (fabs(turn - old_turn) < _EPS)
                );
        
        // These lines are for testing, they should be moved to configurations
        // Bit 0 of control_flag == 0: should we hover?
        // Bit 1 of control_flag == 1: should we use combined yaw mode?
        
        int32_t control_flag = 0x00;
        int32_t combined_yaw = 0x00;
        
        int32_t hover = (int32_t) 
                !(
                (fabs(left_right) < _EPS) && 
                (fabs(front_back) < _EPS) && 
                (fabs(up_down) < _EPS) && 
                (fabs(turn) < _EPS)
                );
        control_flag |= (hover << 0);
        control_flag |= (combined_yaw << 1);
        //ROS_INFO (">>> Control Flag: %d", control_flag);
        
        old_left_right = left_right;
        old_front_back = front_back;
        old_up_down = up_down;
        old_turn = turn;
        //is_changed = true;
        if ((is_changed) || (hover))
        {
            ardrone_tool_set_progressive_cmd(control_flag, left_right, front_back, up_down, turn, 0.0, 0.0);
        }

    }
    vp_os_mutex_unlock(&twist_lock);
	return C_OK;
}
C_RESULT update_gamepad(void) {

	static int32_t start;
    static float phi, theta, gaz, yaw;
	static int cmd_mode = 0;
	static int32_t animation = 0;
	static char *animations[] = {
		"PHI_M30_DEG","PHI_30_DEG","THETA_M30_DEG","THETA_30_DEG",
		"THETA_20DEG_YAW_200DEG","THETA_20DEG_YAW_M200DEG",
		"Turnaround","Turnaround & Down","Turn Shake","Turn Dance",
		"Roll Dance","Tilt Dance","VZ_DANCE","Wave",
		"PHI_THETA_MIXED","DOUBLE_PHI_THETA_MIXED",
		"Front Flip","Back Flip","Left Flip","Right Flip"
	};

	struct js_event js_e_buffer[64];
	ssize_t res = read(joy_dev, js_e_buffer, sizeof(struct js_event) * 64);

	if( !res || (res < 0 && errno == EAGAIN) )
		return C_OK;

	if( res < 0 )
		return C_FAIL;

	if (res < (int) sizeof(struct js_event))// If non-complete bloc: ignored
		return C_OK;

	// Buffer decomposition in blocs (if the last is incomplete, it's ignored)
	bool_t refresh_values = FALSE;
	int32_t idx = 0;
	
	for (idx = 0; idx < res / sizeof(struct js_event); idx++) {

		unsigned char type = js_e_buffer[idx].type;
		unsigned char number = js_e_buffer[idx].number;
		short value = js_e_buffer[idx].value;

		if ( type & JS_EVENT_INIT ) {

			break;
		}
		else if ( type & JS_EVENT_BUTTON ) {
			
			switch( number ) {

				case BUTTON_START :
					if( value == 1 ){
						start ^= 1;
						ardrone_tool_set_ui_pad_start( start );
						g_autopilot = FALSE;
					}
					break;
				case BUTTON_SELECT :
					if( value == 1 ){
						ardrone_tool_set_ui_pad_select(js_e_buffer[idx].value);
						return C_OK;
					}
				case BUTTON_ZAP:
					if( value == 1 ){
						// Using the zap button to pass in a notification to the agent
						// instead of changing the camera (maybe i should move zap to a hat)
						// a button that sets a auto-hover mode might be good too, but tomorrow
						// note: in the event you could do it fast enough (you can't) you would overwrite
						// a previous press before it gets sent
						g_pass_button = BUTTON_ZAP;
					}
					break;
				case BUTTON_HOVER:
					// reset values and set hover mode regardless of current command mode
					// this operates outside of the normal handling so refreshing values isn't necessary
					// autopilot will still be cancelled though
					if( value == 1 ){
						g_autopilot = FALSE;
						phi = 0; theta = 0; gaz = 0; yaw = 0;
						ardrone_tool_set_progressive_cmd(0,0,0,0,0,0,0);
					}
					break;
				case BUTTON_UP:
					if( value == 1 ){
						phi = 0; theta = -0.1; gaz = 0; yaw = 0;
					}else{
						phi = 0; theta = 0; gaz = 0; yaw = 0;
					}
					refresh_values = TRUE;
					break;
				case BUTTON_DOWN:
					if( value == 1 ){
						phi = 0; theta = 0.1; gaz = 0; yaw = 0;
					}else{
						phi = 0; theta = 0; gaz = 0; yaw = 0;
					}
					refresh_values = TRUE;
					break;
				case BUTTON_LEFT:
					if( value == 1 ){
						phi = -0.1; theta = 0; gaz = 0; yaw = 0;
					}else{
						phi = 0; theta = 0; gaz = 0; yaw = 0;
					}
					refresh_values = TRUE;
					break;
				case BUTTON_RIGHT:
					if( value == 1 ){
						phi = 0.1; theta = 0; gaz = 0; yaw = 0;
					}else{
						phi = 0; theta = 0; gaz = 0; yaw = 0;
					}
					refresh_values = TRUE;
					break;
				case BUTTON_L1:
					if( value == 1 ){
						animation++;
						if( animation >= ARDRONE_NB_ANIM_MAYDAY ){
							animation = 0;
						}
						PRINT("Switched flight animation to %s\n", animations[animation]);
					}
					break;
				case BUTTON_R1:
					if( value == 1 ){
						PRINT("Performing flight animation %s\n", animations[animation]);
						ardrone_at_set_anim( animation, MAYDAY_TIMEOUT[animation] );
					}
					break;
				case BUTTON_L2:
					if( value == 1 ){
						phi = 0; theta = 0; gaz = 0; yaw = -0.2;
					}else{
						phi = 0; theta = 0; gaz = 0; yaw = 0;
					}
					refresh_values = TRUE;
					break;
				case BUTTON_R2:
					if( value == 1 ){
						phi = 0; theta = 0; gaz = 0; yaw = 0.2;
					}else{
						phi = 0; theta = 0; gaz = 0; yaw = 0;
					}
					refresh_values = TRUE;
					break;
				case BUTTON_FTRIM:
					if( value == 1 ){
						ardrone_at_set_flat_trim();
						PRINT("Flat trim request sent\n");
					}
					break;
				case BUTTON_AUTO:
					if( value == 1 ){
						if (g_autopilot) {
							refresh_values = TRUE;
						}
						else {
							g_autopilot = TRUE;
						}
					}
					break;
				case BUTTON_LHAT:
					if( value == 1 ){
						if( cmd_mode == 0 ){
							PRINT("ACTIVE mode set. auto-hover disabled\n");
							cmd_mode = 1;
						}else{
							PRINT("ASSISTED mode set. auto-hover enabled\n");
							cmd_mode = 0;
						}
					}
			}

		}
		else if (type & JS_EVENT_AXIS ) {
		    
			if (number == AXIS_PHI || number == AXIS_THETA || number == AXIS_GAZ || number == AXIS_YAW) {
				refresh_values = TRUE;
				float angle = value / (float)SHRT_MAX;
				switch (number) {
					case AXIS_PHI:
						phi = angle;
						break;
					case AXIS_THETA:
						theta = angle;
						break;
					case AXIS_GAZ:
						gaz = ( angle * -1 );
						break;
					case AXIS_YAW:
						yaw = angle;
						break;
				}
			}
		}

	} // loop over events


	if (refresh_values) {

		g_autopilot = FALSE;
		if( phi == 0 && theta == 0 && gaz == 0 && yaw == 0 ){
			ardrone_tool_set_progressive_cmd(cmd_mode,0,0,0,0,0,0);
		}else{
			ardrone_tool_set_progressive_cmd(1,phi,theta,gaz,yaw,0,0);
		}
		//set(phi, theta, gaz, yaw);		
	}

	return C_OK;
}
C_RESULT update_gamepad(void) {

	static int32_t start;
    static float phi, theta, gaz, yaw;

	struct js_event js_e_buffer[64];
	ssize_t res = read(joy_dev, js_e_buffer, sizeof(struct js_event) * 64);

	if( !res || (res < 0 && errno == EAGAIN) )
		return C_OK;

	if( res < 0 )
		return C_FAIL;

	if (res < (int) sizeof(struct js_event))// If non-complete bloc: ignored
		return C_OK;

	// Buffer decomposition in blocs (if the last is incomplete, it's ignored)
	bool_t refresh_values = FALSE;
	int32_t idx = 0;
	for (idx = 0; idx < res / sizeof(struct js_event); idx++) {

		unsigned char type = js_e_buffer[idx].type;
		unsigned char number = js_e_buffer[idx].number;
		short value = js_e_buffer[idx].value;

		if (type & JS_EVENT_INIT ) {

			break;
		}
		else if (!value) {

			break;
		}
		else if (type & JS_EVENT_BUTTON ) {

			switch(number ) {

				case BUTTON_START :
					start ^= 1;
					ardrone_tool_set_ui_pad_start( start );
					g_autopilot = FALSE;
					break;
				case BUTTON_SELECT :
					ardrone_tool_set_ui_pad_select(js_e_buffer[idx].value);
					return C_OK;
				case BUTTON_ZAP:
					zap();
					break;
				case BUTTON_AUTO:
					if (g_autopilot) {
						refresh_values = TRUE;
					}
					else {
						g_autopilot = TRUE;
					}
					break;
			}

		}
		else if (type & JS_EVENT_AXIS ) {
		    
			if (number != AXIS_IGNORE3 && number != AXIS_IGNORE4) {
				refresh_values = TRUE;
				float angle = value / (float)SHRT_MAX;
				switch (number) {
					case AXIS_PHI:
						phi = angle;
						break;
					case AXIS_THETA:
						theta = angle;
						break;
					case AXIS_GAZ:
						gaz = angle;
						break;
					case AXIS_YAW:
						yaw = angle;
						break;
				}
			}
		}

	} // loop over events


	if (refresh_values) {

		g_autopilot = FALSE;
		
		set(phi, theta, gaz, yaw);		
	}

	return C_OK;
}
示例#19
0
C_RESULT take_off(void *arg) {
  ardrone_tool_set_ui_pad_select(0);
  ardrone_tool_set_ui_pad_start(1);
  return C_OK;
}
示例#20
0
C_RESULT update_radioGP(void)
{
  static float32_t roll = 0, pitch = 0, gaz=0, yaw=0;
  static bool_t refresh_values = FALSE;
  ssize_t res;
  static struct js_event js_e_buffer[64];

  res = read(joy_dev, js_e_buffer, sizeof(struct js_event) * 64);

  if( !res || (res < 0 && errno == EAGAIN) )
    return C_OK;

  if( res < 0 )
    return C_FAIL;

  if (res < (int) sizeof(struct js_event))// If non-complete bloc: ignored
    return C_OK;

  // Buffer decomposition in blocs (if the last is incomplete, it's ignored)
  int32_t idx = 0;
  refresh_values = FALSE;
  for (idx = 0; idx < res / sizeof(struct js_event); idx++)
  {
    if(js_e_buffer[idx].type & JS_EVENT_INIT )// If Init, the first values are ignored
    {
      break;
    }
    else if(js_e_buffer[idx].type & JS_EVENT_BUTTON )// Event Button detected
    {
      switch( js_e_buffer[idx].number )
      {
        case GP_BOARD_LEFT :
					ardrone_tool_set_ui_pad_start(js_e_buffer[idx].value);
					break;
        case GP_SIDE_RIGHT :
					ardrone_tool_set_ui_pad_r2(js_e_buffer[idx].value);
					break;
        case GP_IMPULSE :
					ardrone_tool_set_ui_pad_select(js_e_buffer[idx].value);
					break;
        case GP_SIDE_LEFT_DOWN :
					ardrone_tool_set_ui_pad_ad(js_e_buffer[idx].value);
					break;
        case GP_SIDE_LEFT_UP :
					ardrone_tool_set_ui_pad_ad(js_e_buffer[idx].value);
					break;
        default: break;
      }
    }
    else if(js_e_buffer[idx].type & JS_EVENT_AXIS )// Event Axis detected
    {
      refresh_values = TRUE;
      switch( js_e_buffer[idx].number )
      {
        case GP_PITCH:
          pitch = js_e_buffer[idx].value;
          break;
        case GP_GAZ:
          gaz = js_e_buffer[idx].value;
          break;
        case GP_ROLL:
          roll = js_e_buffer[idx].value;
          break;
        case GP_PID:
          break;
        case GP_YAW:
          yaw = js_e_buffer[idx].value;
          break;
        default:
          break;
      }
    }
    else
    {// TODO: default: ERROR (non-supported)
    }
  }

  if(refresh_values)// Axis values to refresh
    {
       ardrone_at_set_progress_cmd( 1,
                                               roll/25000.0,
                                               pitch/25000.0,
                                               -gaz/25000.0,
                                               yaw/25000.0);
    }

  return C_OK;
}