Subversion Repositories Projects

Rev

Blame | Last modification | View Log | RSS feed

#include <linux/joystick.h>
#include "main.h"
#include "gamepad.h"
#include "frame.h"

volatile int *Axis = NULL;
volatile char *Button = NULL;
volatile float Sensitivity = 1.0;
int NumberOfAxesAvailiable;
int NumberOfButtonsAvailiable;
char GamepadConnected[30];
u8 IsActive = 0;
u8 ProgramSelect = 0;

int recordingButtonTemp = 125;
int padFd;
struct js_event js;

struct str_ExternControl externControl;                 //struct for controlling MikroKopter
struct str_ExternControl externControlGier;             //struct for controlling Yaw (Gier) only

u8 gamepad_values_convert_for_cam(int tmpvalue){
        u8 tmp;
        double tmpdouble = tmpvalue;
        tmp = ((((tmpdouble/(MaxAxisValue))-1)*125)-131)*-1;
        if(tmp == 0){tmp = 255;}
        return(tmp);
}

//>> Converting gamepad values to values readable by a MikroKopter
//------------------------------------------------------------------------------------------------------
u8 gamepad_values_convert_for_kopter(int tmpvalue){
        u8 tmp;
        double tmpdouble = tmpvalue;
        tmp = ((((tmpdouble/(MaxAxisValue*Sensitivity))-1)*125)-131)*-1;
        /*Increase values exponentially
        if(tmpvalue < 0){
                tmpdouble = tmpvalue*-1;
        }else{tmpdouble = tmpvalue;}
        tmp = ((30497*tmpdouble*tmpdouble*tmpdouble)/11187226521286200+(10667778*tmpdouble*tmpdouble)/532725072442200+(2592340312*tmpdouble)/11187226521286);
        if(tmpvalue < 0){
                tmp = (tmp*-1)+255;
        }
        */

        return(tmp);
}

u8 gamepad_values_convert_for_kopter_gas(int tmpvalue){
        u8 tmp;
        double tmpdouble = tmpvalue;
        tmp = ((((tmpdouble/(MaxAxisValue))-1)*125)-131)*-1;
        return(tmp);
}

int check_if_button_pushed(){
        read_gamepad_data();
        int buttonpushed = -1;
        for (int i = 0; i < NumberOfButtonsAvailiable; i++)
        {
                if(Button[i] != 0){
                        buttonpushed = i;
                }
        }
        return(buttonpushed);
}

//>> Check if controls are active
//------------------------------------------------------------------------------------------------------
void check_if_controls_active(){
        if(check_if_button_pushed() == GamepadLayout[17] && IsActive == 0){
                IsActive = 1;
                while(1){if(!value_sum(0)){break;};}
        }else if(check_if_button_pushed() == GamepadLayout[17] && IsActive == 1){
                IsActive = 0;
                while(1){if(!value_sum(0)){break;};}
        }
}
//>> Check if program has been switched
//------------------------------------------------------------------------------------------------------
void check_program_switch(){
        if(check_if_button_pushed() == GamepadLayout[11]){
                frame_print("", 1, 0);
                ProgramSelect = 1;
        }else if(check_if_button_pushed() == GamepadLayout[12]){
                frame_print("", 1, 0);
                ProgramSelect = 2;
        }
}

//>> Check if sensitivity of the controls has been adjusted
//------------------------------------------------------------------------------------------------------
void get_sensitivity(){
        if(check_if_button_pushed() == GamepadLayout[15] && Sensitivity <= 2.0){
                if(Sensitivity < 2){buzzer_short(1);}
                Sensitivity += 0.2;
                while(1){if(!value_sum(0)){break;};}
        }else if(check_if_button_pushed() == GamepadLayout[16] && Sensitivity > 1.0){
                if(Sensitivity > 1){buzzer_short(1);}
                Sensitivity -= 0.2;
                while(1){if(!value_sum(0)){break;};}
        }
}

//>> Preparing Data for remotely controlling a Camera-Gimbal
//------------------------------------------------------------------------------------------------------
void create_data_camera(serial_data_struct* pdata_package_camera_control, serial_data_struct* pdata_package_camera_control_gier){
        pdata_package_camera_control->data[0] = gamepad_values_convert_for_cam(Axis[GamepadLayout[0]]);                                                                                         //Nick
        pdata_package_camera_control->data[1] = gamepad_values_convert_for_cam(Axis[GamepadLayout[1]]);                                                                                         //Roll
        pdata_package_camera_control->data[2] = gamepad_values_convert_for_cam(Axis[GamepadLayout[3]]);                                                                                         //
        if(Button[GamepadLayout[8]] > 0){recordingButtonTemp = 131;}else if(Button[GamepadLayout[9]] > 0){recordingButtonTemp = 125;}
        pdata_package_camera_control->data[3] = recordingButtonTemp;
        if(Button[GamepadLayout[10]]){pdata_package_camera_control->data[4] = 131;}else{pdata_package_camera_control->data[4] = 125;}
        int i = 5;
        while(i < 12){
                pdata_package_camera_control->data[i] = 0;
                i++;
        }
        //Add Yaw (Gier)-funcionality
        externControlGier.Gier = gamepad_values_convert_for_kopter(Axis[GamepadLayout[2]]);
        externControlGier.Config = EC_VALID | EC_GAS_ADD;
        externControlGier.Frame = 'z';                                                                          //character for echo
        u8 *tmpData = (unsigned char *) &externControlGier;
        for (int i = 0; i < pdata_package_camera_control_gier->cmdLength; ++i)
        {
                pdata_package_camera_control_gier->data[i] = tmpData[i];
        }

        //Print out values on screen
        char tmpbuffer[255];
        sprintf(tmpbuffer, "Nick: %d    \n     Roll: %d     \n     Gier: %d     \n     Zoom: %d     \n     Aufnahme: %d    \n     Auslösung: %d", pdata_package_camera_control->data[0], pdata_package_camera_control->data[1], pdata_package_camera_control_gier->data[2], pdata_package_camera_control->data[2], pdata_package_camera_control->data[3], pdata_package_camera_control->data[4]);
        frame_values("VALUES", 5, 2);
        frame_values(tmpbuffer, 5, 4);
}

//>> Preparing Data for remotely controlling a MikroKopter
//------------------------------------------------------------------------------------------------------
void create_data_kopter(serial_data_struct* pdata_package_kopter_control){
        if(check_if_button_pushed() == GamepadLayout[13]){                              //Motor start
                externControl.Nick = 131;
                externControl.Roll = 131;
                externControl.Gier = 131;
                externControl.Gas = 131;       
        }else if(check_if_button_pushed() == GamepadLayout[14]){                //Motor stop
                externControl.Nick = 131;
                externControl.Roll = 125;
                externControl.Gier = 125;
                externControl.Gas = 131;
        }else{
                externControl.Nick = gamepad_values_convert_for_kopter(Axis[GamepadLayout[4]]);
                externControl.Roll = gamepad_values_convert_for_kopter(Axis[GamepadLayout[5]]);
                externControl.Gier = gamepad_values_convert_for_kopter(Axis[GamepadLayout[6]]);
                externControl.Gas = gamepad_values_convert_for_kopter_gas(Axis[GamepadLayout[7]]);
        }
        externControl.Config = EC_VALID | EC_GAS_ADD | EC_IGNORE_RC;
        externControl.Frame = 'z';                                                                              //character for echo
        u8 *tmpData = (unsigned char *) &externControl;
        for (int i = 0; i < pdata_package_kopter_control->cmdLength; ++i)
        {
                pdata_package_kopter_control->data[i] = tmpData[i];
        }
        //Print out values on screen
        char tmpbuffer[255];
        sprintf(tmpbuffer, "Nick: %d    \n     Roll: %d     \n     Gier: %d     \n     Gas : %d   \n", pdata_package_kopter_control->data[0], pdata_package_kopter_control->data[1], pdata_package_kopter_control->data[2], pdata_package_kopter_control->data[3]);
        frame_values("VALUES", 5, 2);
        frame_values(tmpbuffer, 5, 4);
}

void read_gamepad_data(){
        read(padFd, &js, sizeof(struct js_event));
        switch (js.type & ~JS_EVENT_INIT)
        {
                case JS_EVENT_AXIS:
                        Axis   [ js.number ] = js.value;
                        break;
                case JS_EVENT_BUTTON:
                        Button [ js.number ] = js.value;
                        break;
        }
}

//>> Initialize Gamepad
//------------------------------------------------------------------------------------------------------
void gamepad_init(){
        if((padFd = open(GAME_PAD, O_RDONLY)) == -1)
        {
                printf( "Couldn't open gamepad\n" );
        }
        ioctl( padFd, JSIOCGAXES, &NumberOfAxesAvailiable );
        ioctl( padFd, JSIOCGBUTTONS, &NumberOfButtonsAvailiable );
        ioctl( padFd, JSIOCGNAME(80), &GamepadConnected );
        Axis = (int *) calloc( NumberOfAxesAvailiable, sizeof( int ) );
        Button = (char *) calloc( NumberOfButtonsAvailiable, sizeof( char ) );
        fcntl( padFd, F_SETFL, O_NONBLOCK );    /* use non-blocking mode */
}