Revision 74c0e6394dc5a2a6fb703406de719b47a626cb3b authored by ziqingma on 22 October 2023, 21:33:01 UTC, committed by ziqingma on 23 October 2023, 08:42:43 UTC
CG shift due to tilt issue, add takeoff test flightplan in cyberzoo Update guidance_indi.c
1 parent 6b317f2
nps_radio_control_joystick.c
/*
* Copyright (C) 2009 Antoine Drouin <poinix@gmail.com>
* Copyright (C) 2012 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* @file nps_radio_control_joystick.c
* Direct RC control for NPS with a standard joystick using SDL.
*
* Simple DirectMedia Layer library is used for cross-platform support.
* Joystick button and axes are mapped to RC commands directly with defines.
*
* You must have a joystick with either:
* - 4 axes and 3 buttons, or
* - 5 axes
*
* First you should run sw/ground_segment/joystick/test_stick to determine
* the indices of the physical axes and buttons on your joystick (and to test
* that it actually works). Then you can assign each axis and button to a
* command in your airframe file.
*
* The default axes are Roll = 0, Pitch = 1, Yaw = 2 and Throttle = 3.
* The default buttons are Manual = 0, Auto1 = 1, Auto2 = 2.
*
* Example for 4 axes and 3 buttons using a joystick with 7 axes and 5 buttons:
* @verbatim
* <section name="SIMULATOR" prefix="NPS_">
* ...
* <define name="JS_AXIS_ROLL" value="2"/> <!-- Use joystick axis 2 for roll -->
* <!-- Use joystick axis 1 for pitch (default) -->
* <define name="JS_AXIS_YAW" value="3"/> <!-- Use joystick axis 3 for yaw -->
* <define name="JS_AXIS_ROLL" value="6"/> <!-- Use joystick axis 6 for throttle -->
* <define name="JS_BUTTON_MODE_MANUAL" value="3"/> <!-- Use joystick button 3 for manual -->
* <!-- Use joystick button 1 for auto1 (default) -->
* <!-- Use joystick button 2 for auto2 (default) -->
* </section>
* @endverbatim
*
* One can define NPS_JS_AXIS_MODE to use an axis instead of buttons to change
* You will need a 5-axis joystick.
*
* If you need to reverse the direction of any axis, simply use:
* @verbatim
* <define name="JS_AXIS_PITCH_REVERSE" value="1"/>
* <!-- value="1" is required, setting to zero or omitting disables reversing -->
* @endverbatim
*
* At this point, no other functionality or channels are supported for R/C control.
*
*/
#include "nps_radio_control.h"
#include "nps_radio_control_joystick.h"
// for NPS_JS_AXIS_MODE
#include "generated/airframe.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <SDL/SDL.h>
// axes indice
#ifndef NPS_JS_AXIS_ROLL
#define NPS_JS_AXIS_ROLL 0
#endif
#ifndef NPS_JS_AXIS_PITCH
#define NPS_JS_AXIS_PITCH 1
#endif
#ifndef NPS_JS_AXIS_YAW
#define NPS_JS_AXIS_YAW 2
#endif
#ifndef NPS_JS_AXIS_THROTTLE
#define NPS_JS_AXIS_THROTTLE 3
#endif
#ifndef NPS_JS_AXIS_MODE
#define JS_NB_AXIS 4
#else
#define JS_NB_AXIS 5
#endif
// buttons to switch modes
#ifndef NPS_JS_BUTTON_MODE_MANUAL
#define NPS_JS_BUTTON_MODE_MANUAL 1
#endif
#ifndef NPS_JS_BUTTON_MODE_AUTO1
#define NPS_JS_BUTTON_MODE_AUTO1 2
#endif
#ifndef NPS_JS_BUTTON_MODE_AUTO2
#define NPS_JS_BUTTON_MODE_AUTO2 3
#endif
#ifndef NPS_JS_AXIS_MODE
#define JS_NB_BUTTONS 3
#else
#define JS_NB_BUTTONS 0
#endif
struct NpsJoystick nps_joystick;
SDL_Joystick *sdl_joystick;
SDL_Event sdl_event;
/**
* Initializes SDL and the joystick.
*
* Function exits with -1 if fails
*
* @param device string integer of desired joystick device
*
* @returns 0 on success
*/
int nps_radio_control_joystick_init(const char *device)
{
nps_joystick.throttle = 0.5;
nps_joystick.roll = 0.;
nps_joystick.pitch = 0.;
nps_joystick.yaw = 0.;
nps_joystick.mode = MODE_SWITCH_AUTO2;
//Convert device index string to integer
int device_index = atoi(device);
//Initialize SDL with joystick support and event support (through video)
if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) < 0) {
printf("Could not initialize SDL: %s.\n", SDL_GetError());
exit(-1);
}
//Quit SDL at exit
atexit(SDL_Quit);
//Start the event handler, disable all but joystick button events and quit handler
SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
SDL_EventState(SDL_KEYUP, SDL_IGNORE);
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);
SDL_EventState(SDL_JOYAXISMOTION, SDL_IGNORE);
SDL_EventState(SDL_JOYBALLMOTION, SDL_IGNORE);
SDL_EventState(SDL_JOYHATMOTION, SDL_IGNORE);
//SDL_EventState(SDL_JOYBUTTONDOWN,SDL_IGNORE);
SDL_EventState(SDL_JOYBUTTONUP, SDL_IGNORE);
SDL_EventState(SDL_VIDEORESIZE, SDL_IGNORE);
SDL_EventState(SDL_VIDEOEXPOSE, SDL_IGNORE);
//SDL_EventState(SDL_QUIT,SDL_IGNORE);
SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
//Check there are actually joysticks attached
if (!SDL_NumJoysticks()) {
printf("No joysticks attached! Quitting.\n");
exit(-1);
}
//Open the desired joystick and make sure it will work
sdl_joystick = SDL_JoystickOpen(device_index);
if (!sdl_joystick) {
printf("Joystick corresponding to SDL Index %d failed to open! Exiting.\n", device_index);
exit(-1);
} else if (SDL_JoystickNumAxes(sdl_joystick) < JS_NB_AXIS) {
printf("Selected joystick does not support enough axes!\n");
printf("Number of axes required: %i\n", JS_NB_AXIS);
printf("Number of axes available: %i\n", SDL_JoystickNumAxes(sdl_joystick));
SDL_JoystickClose(sdl_joystick);
exit(-1);
} else if (SDL_JoystickNumButtons(sdl_joystick) < JS_NB_BUTTONS) {
printf("Selected joystick does not support enough buttons!\n");
printf("Buttons supported: %d needed: %d\n", SDL_JoystickNumButtons(sdl_joystick), JS_NB_BUTTONS);
SDL_JoystickClose(sdl_joystick);
exit(-1);
} else {
printf("Using joystick named: %s\n", SDL_JoystickName(device_index));
}
return 0;
}
/**
* Updates joystick buttons from events, directly reads current axis positions.
*/
void nps_radio_control_joystick_update(void)
{
#if NPS_JS_AXIS_THROTTLE_REVERSED
nps_joystick.throttle = ((float)(-1 * SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_THROTTLE)) - 32767.) / -65534.;
#else
nps_joystick.throttle = ((float)(SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_THROTTLE)) - 32767.) / -65534.;
#endif
#if NPS_JS_AXIS_ROLL_REVERSED
nps_joystick.roll = (float)(-1 * SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_ROLL)) / 32767.;
#else
nps_joystick.roll = (float)(SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_ROLL)) / 32767.;
#endif
#if NPS_JS_AXIS_PITCH_REVERSED
nps_joystick.pitch = (float)(-1 * SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_PITCH)) / 32767.;
#else
nps_joystick.pitch = (float)(SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_PITCH)) / 32767.;
#endif
#if NPS_JS_AXIS_YAW_REVERSED
nps_joystick.yaw = (float)(-1 * SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_YAW)) / 32767.;
#else
nps_joystick.yaw = (float)(SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_YAW)) / 32767.;
#endif
// if an axis is asigned to the mode, use it instead of the buttons
#ifdef NPS_JS_AXIS_MODE
#if NPS_JS_AXIS_MODE_REVERSED
nps_joystick.mode = (float)(-1 * SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_MODE)) / 32767.;
#else
nps_joystick.mode = (float)(SDL_JoystickGetAxis(sdl_joystick, NPS_JS_AXIS_MODE)) / 32767.;
#endif
#endif
while (SDL_PollEvent(&sdl_event)) {
switch (sdl_event.type) {
case SDL_JOYBUTTONDOWN: {
switch (sdl_event.jbutton.button) {
#ifndef NPS_JS_AXIS_MODE
case NPS_JS_BUTTON_MODE_MANUAL:
nps_joystick.mode = MODE_SWITCH_MANUAL;
break;
case NPS_JS_BUTTON_MODE_AUTO1:
nps_joystick.mode = MODE_SWITCH_AUTO1;
break;
case NPS_JS_BUTTON_MODE_AUTO2:
nps_joystick.mode = MODE_SWITCH_AUTO2;
break;
#endif
default:
//ignore
break;
}
}
break;
case SDL_QUIT:
printf("Quitting...\n");
exit(-1);
break;
default:
//do nothing
printf("unknown SDL event!!!\n");
break;
}
}
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...