Skip to content

Commit

Permalink
Linux xbox controller working
Browse files Browse the repository at this point in the history
  • Loading branch information
sytelus committed Aug 31, 2017
1 parent 431059e commit 62c2c6e
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 13 deletions.
89 changes: 82 additions & 7 deletions Unreal/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ struct SimJoyStick::impl {

#else

#include <limits>
#include <fcntl.h>
#include <iostream>
#include <string>
#include <sstream>
#include <iostream>
#include <libudev.h>
#include "unistd.h"

//implementation for unsupported OS
Expand Down Expand Up @@ -203,14 +205,35 @@ struct SimJoyStick::impl {
close(fd_);
}

static float normalizeAxisVal(int axis_val, bool wide, bool zero2One, bool reversed)
{
float min_val = wide ? -32768 : -16384;
float max_val = wide ? 32767 : 16383;

float val = (axis_val - min_val) / (max_val - min_val);
if (zero2One) {
if (reversed)
val = 1 - val;
}
else {
val = 2*val - 1;
if (reversed)
val *= -1;
}

return val;
}

void getJoyStickState(unsigned int index, SimJoyStick::State& state, const AxisMaps& maps)
{
unused(maps);

static constexpr bool blocking = false;

//if this is new indec
if (index != last_index_) {
//getJoystickInfo(1, manufacturerID, productID, state.message);

//close previos one
if (fd_ >= 0)
close(fd_);
Expand Down Expand Up @@ -246,12 +269,26 @@ struct SimJoyStick::impl {
state.buttons |= (1 << event_.number);
}
else if (event_.isAxis()) {
switch(event_.number) {
case 0: state.left_y = event_.value; break;
case 1: state.right_x = event_.value; break;
case 2: state.right_y = event_.value; break;
case 3: state.left_x = event_.value; break;
default: break;
if (device_type > 0) { //RCs like FrSky Taranis
switch(event_.number) {
case 0: state.left_y = event_.value; break;
case 1: state.right_x = event_.value; break;
case 2: state.right_y = event_.value; break;
case 3: state.left_x = event_.value; break;
default: break;
}
}
else { //XBox
switch(event_.number) {
case 0: state.left_x = normalizeAxisVal(event_.value, true, false, false); break;
case 1: state.left_y = normalizeAxisVal(event_.value, false, true, true); break;
case 2: state.left_z = normalizeAxisVal(event_.value, true, false, false); break;
case 3: state.right_x = normalizeAxisVal(event_.value, true, false, false); break;
case 4: state.right_y = normalizeAxisVal(event_.value, true, false, false); break;
case 5: state.right_z = normalizeAxisVal(event_.value, true, false, false); break;

default: break;
}
}
}
//else ignore
Expand All @@ -261,10 +298,48 @@ struct SimJoyStick::impl {
state.is_valid = false;
}

// bool getJoystickInfo(int index, std::string& manufacturerID, std::string& productID, std::string& message)
// {
// manufacturerID = productID = "";
// // Use udev to look up the product and manufacturer IDs
// struct udev *udev = udev_new();
// if (udev) {
// char sysname[32];
// std::snprintf(sysname, sizeof(sysname), "js%u", index);
// struct udev_device *dev = udev_device_new_from_subsystem_sysname(udev, "input", sysname);
// dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device");
// if (!dev)
// {
// message = "Unable to find parent USB device";
// return false;
// }

// std::stringstream ss;
// ss << std::hex << udev_device_get_sysattr_value(dev, "idVendor");
// ss >> manufacturerID;

// ss.clear();
// ss.str("");
// ss << std::hex << udev_device_get_sysattr_value(dev, "idProduct");
// ss >> productID;

// udev_device_unref(dev);
// }
// else
// {
// message = "Cannot create udev";
// return false;
// }
// udev_unref(udev);
// return true;
// }

private:
unsigned int last_index_ = -1;
int fd_ = -1;
JoystickEvent event_;
std::string manufacturerID, productID;
int device_type = 0;
};

#endif
Expand Down
16 changes: 10 additions & 6 deletions docs/remote_control.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ To fly manually, you need remote control or RC. If you don't have one then you c

## RC Setup for Default Config

By default AirSim uses [simple_flight](simple_flight.md) as its flight controller which needs RC that can be connected via USB port to your computer.
By default AirSim uses [simple_flight](simple_flight.md) as its flight controller which connects to RC via USB port to your computer.

### Option 1: XBox 360 USB Gamepad
You can either use XBox controller or [FrSky Taranis X9D Plus](https://hobbyking.com/en_us/frsky-2-4ghz-accst-taranis-x9d-plus-and-x8r-combo-digital-telemetry-radio-system-mode-2.html). Note that XBox 360 controller is not precise enough and is not recommended if you wanted more real world experience. See FAQ below if things are not working.

XBox 360 controller is not precise enough and is not recommended if you wanted more real world experience. However if that's all you have then connect it up, restart Unreal and it should just work. You will see message printed on screen that USB RC is detected. If its not working then see the FAQ section below for troubleshooting.
### Other Devices
AirSim can detect large variety of devices however devices other than above *might* need extra configuration. In future we will add ability to set this config through settings.json. For now, if things are not working then you might want to try workarounds such as [x360ce](http://www.x360ce.com/) or chnage code in [SimJoystick.cpp file](/Unreal/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp#L50).

### Option 2: FrSky Taranis X9D Plus
### Note on FrSky Taranis X9D Plus

[FrSky Taranis X9D Plus](https://hobbyking.com/en_us/frsky-2-4ghz-accst-taranis-x9d-plus-and-x8r-combo-digital-telemetry-radio-system-mode-2.html) is real UAV remote control with an advantage that it has USB port so it can be directly connected to PC. You can [download our config file](../Unreal/Plugins/AirSim/Dependencies/x360ce/AirSim_FrSkyTaranis.bin) and [follow this tutorial](https://www.youtube.com/watch?v=qe-13Gyb0sw) to import it in your RC. You should then see "sim" model in RC with all channels configured properly. After you plugin RC via USB to PC, it should just work and AirSim will show message printed on screen that USB RC is detected. If its not working then see the FAQ section below for troubleshooting.
[FrSky Taranis X9D Plus](https://hobbyking.com/en_us/frsky-2-4ghz-accst-taranis-x9d-plus-and-x8r-combo-digital-telemetry-radio-system-mode-2.html) is real UAV remote control with an advantage that it has USB port so it can be directly connected to PC. You can [download AirSim config file](../Unreal/Plugins/AirSim/Dependencies/x360ce/AirSim_FrSkyTaranis.bin) and [follow this tutorial](https://www.youtube.com/watch?v=qe-13Gyb0sw) to import it in your RC. You should then see "sim" model in RC with all channels configured properly.

### Note on Linux
Currently default config on Linux is for using Xbox controller. This means other devices might not work properly. In future we will add ability to configure RC in settings.json but for now you *might* have to change code in [SimJoystick.cpp file](/Unreal/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp#L340) to use other devices.

## RC Setup for PX4

Expand Down Expand Up @@ -52,7 +56,7 @@ This typically happens if you have multiple RCs and or XBox/Playstation gamepads

#### Vehicle seems unstable when using XBox/PS3 contoller.

Typical gamepads are not very precise and have lot of random noise. Most of the times you may see significant offsets as well (i.e. output is not zero when sticks are at zero). So this behaviour is expected.
Regular gamepads are not very precise and have lot of random noise. Most of the times you may see significant offsets as well (i.e. output is not zero when sticks are at zero). So this behaviour is expected.

#### Where is RC calibration in AirSim?

Expand Down

0 comments on commit 62c2c6e

Please sign in to comment.