Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for TMX Force Feedback #8

Merged
merged 6 commits into from
Jul 27, 2017
Merged

Conversation

pastaq
Copy link
Contributor

@pastaq pastaq commented Jul 23, 2017

./tmdrv.py -d thrustmaster_tmx_ff results in normal initialization.

- ./tmdrv.py -d thrustmaster_tmx_ff results ins normal initialization.
TMX Force Feedback and TMX Pro are the same device, packaged with
different pedals.
@her001
Copy link
Owner

her001 commented Jul 23, 2017

Greetings! Thanks for your effort in gathering the data and making this pull request.

I am in the process of reviewing your additions. If I find anything that I would like to give feedback on, I will provide it in review comments.

Before this is merged, I'd also like to ask a couple things:

  • Could you run jscal -c on your device and update the configuration in tmdrv_devices/thrustmaster_tmx.py? The data in the jscal variable can be obtained with jscal -p, after calibrating. The dev_by_id variable is the name of the *-joystick file which corresponds to your device in /dev/input/by-id/. This ensures that the wheel starts with sane deadzones, at least.

  • Less critically, I would prefer it if you could rebase the history so that the merge commit (b46ad4a) has been removed.

Copy link
Owner

@her001 her001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things are looking pretty good. These changes I am suggesting are to make tmdrv consistent with the data in the USB captures you provided.

@@ -0,0 +1,9 @@
name = 'Thrustmaster TMX'
idVendor = 0x044f
idProduct = [ 0xb65d, 0xb67e]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing this to the capture data that you provided, it looks like this might not be entirely correct. It looks to me like this should be:

idProduct = [0xb67e, 0xb65d, 0xb67f]

In the Thrustmaster_TMX_2017_07_22(Replug Only).pcap capture file that you provided, packets numbered 466, 570, and 972 appear to indicate that these are the correct product IDs.

idProduct = [ 0xb65d, 0xb67e]
control = [
{'step':1, 'request_type':0x41, 'request':83, 'value':0x0001, 'index':0x0000, 'data':b''},
{'step':2, 'request_type':0x41, 'request':83, 'value':0x0004, 'index':0x0000, 'data':b''},
Copy link
Owner

@her001 her001 Jul 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In step 2, value looks like it should be 0x0007, according to packet number 653 in Thrustmaster_TMX_2017_07_22(Replug Only).pcap.

request to be in line with pcap data
- Fixed a bug that caused tmxdrv.py to crash if jscal could not get
permissions to a joy device.
@pastaq
Copy link
Contributor Author

pastaq commented Jul 25, 2017

Changes included as requested. I also ran into a small bug in tmdrv.py where only check_call was being imported from subprocess, but you were calling subprocess.CalledProcessError later in the file. I likely have an issue with my udev rule as I am only able to run the program as root, and jscal fails every time. I also need to hotplug every time I run tmdrv.py or I get a "usb1.USBErrorNotFound('Device not found or wrong permissions')" error.


traceback without the fix:

blip@Terminus:~/git/tmdrv$ sudo ./tmdrv.py -d thrustmaster_tmx
jscal: can't open joystick device: No such file or directory
Traceback (most recent call last):
File "./tmdrv.py", line 79, in _jscal
check_call(['jscal', '-s', configuration, device_file])
File "/usr/lib/python3.5/subprocess.py", line 271, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['jscal', '-s', '6,1,255,32767,32767,21844,21844,1,3,511,511,1394469,1394469,1,3,511,511,1394469,1394469,1,3,511,511,1394469,1394469,1,0,0,0,536870912,536870912,1,0,0,0,536870912,536870912', '/dev/input/by-id/usb-Thrustmaster_Thrustmaster_TMX_Racing_Wheel-joystick']' returned non-zero exit status 1

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "./tmdrv.py", line 117, in
initialize(args.device)
File "./tmdrv.py", line 75, in initialize
_jscal(device.jscal, "/dev/input/by-id/" + device.dev_by_id)
File "./tmdrv.py", line 82, in _jscal
except subprocess.CalledProcessError as err:
NameError: name 'subprocess' is not defined


Traceback after the fix:

blip@Terminus:~/git/tmdrv$ sudo ./tmdrv.py -d thrustmaster_tmx
jscal: can't open joystick device: No such file or directory
jscal non-zero exit code 1, device may not be calibrated


output of /dev/by-id:

blip@Terminus:~/git/tmdrv$ ls -al /dev/input/by-id/
total 0
drwxr-xr-x 2 root root 260 Jul 24 20:09 .
drwxr-xr-x 4 root root 640 Jul 24 20:09 ..
lrwxrwxrwx 1 root root 10 Jul 24 19:47 usb-046d_Logitech_Webcam_C930e_35FD9CCF-event-if00 -> ../event23
lrwxrwxrwx 1 root root 9 Jul 24 19:47 usb-Blue_Microphones_Yeti_Stereo_Microphone_REV8-event-if03 -> ../event8
lrwxrwxrwx 1 root root 9 Jul 24 19:47 usb-Corsair_Corsair_K70R_Gaming_Keyboard-event-if01 -> ../event5
lrwxrwxrwx 1 root root 9 Jul 24 19:47 usb-Corsair_Corsair_K70R_Gaming_Keyboard-event-kbd -> ../event4
lrwxrwxrwx 1 root root 9 Jul 24 19:47 usb-Corsair_Corsair_K70R_Gaming_Keyboard-if02-event-kbd -> ../event6
lrwxrwxrwx 1 root root 9 Jul 24 19:48 usb-Logitech_USB_Receiver-if02-event-mouse -> ../event7
lrwxrwxrwx 1 root root 9 Jul 24 19:48 usb-Logitech_USB_Receiver-if02-mouse -> ../mouse1
lrwxrwxrwx 1 root root 9 Jul 24 20:09 usb-Thrustmaster_Thrustmaster_TMX_Racing_Wheel-event-joystick -> ../event3
lrwxrwxrwx 1 root root 6 Jul 24 20:09 usb-Thrustmaster_Thrustmaster_TMX_Racing_Wheel-joystick -> ../js0
lrwxrwxrwx 1 root root 9 Jul 24 19:47 usb-Valve_Software_Steam_Controller-event-mouse -> ../event2
lrwxrwxrwx 1 root root 9 Jul 24 19:47 usb-Valve_Software_Steam_Controller-mouse -> ../mouse0


my udev rule from /etc/udev/rules.d/10-local.rules:

SUBSYSTEMS=="usb", ATTRS{product}=="Thrustmaster FFB Wheel", GROUP="users"

@her001
Copy link
Owner

her001 commented Jul 25, 2017

The hot-plugging each time is expected. Right now, tmdrv has no way to handle a device that is already partially or fully initialized; it must go in order. This means that your device has to be unplugged to reset the state that it is in, assuming tmdrv has already been run.

Nice catch on CalledProcessError, thanks for fixing that.

As for your udev rules, you may want to change it to something like:

SUBSYSTEM=="usb", ATTRS{idVendor}=="044f", MODE="0666", GROUP="users"

If this works properly, you should be able to run everything without needing extra permissions.

{'step':2, 'request_type':0x41, 'request':83, 'value':0x0007, 'index':0x0000, 'data':b''},
]
jscal = '6,1,255,32767,32767,21844,21844,1,3,511,511,1394469,1394469,1,3,511,511,1394469,1394469,1,3,511,511,1394469,1394469,1,0,0,0,536870912,536870912,1,0,0,0,536870912,536870912'
dev_by_id = 'usb-Thrustmaster_Thrustmaster_TMX_Racing_Wheel-joystick'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks as though the dev_by_id is correct. You'll still need to adjust the jscal data, after following the instructions I left earlier to calibrate the device. If you need assistance with this, feel free to ask questions.

- Updated the jscal calibration numbers from jscal -p output after a
manual calibration.
- Updated README.md to include easier method for installing jscal for
Ubuntu users.
@pastaq
Copy link
Contributor Author

pastaq commented Jul 26, 2017

Fixed the udev rule. the mode="0666" needed to be mode:="0666" as 50-udev-default.rules was setting it to 0664 after my rule. Now that that is fixed, I am still getting the jscal error when I run tmdrv.py. I have tried jscal from both a source compile as specified in the steps and the joystick package from Ubuntu. I manually ran a jscal -c to calibrate it. I used the output from jscal -p in the jscal data. The only problem when calibrating seemed to be that the wheel started from center at +32767, left went down to 0, and right didn't really go up since centered was already at max. Pedals all went from 0 pushed in 100% to 1023 all the way off. Dpad for "axis" 4 & 5 was -1, 0, 1

With the jscal calibration settings in thrustmastter_tmx.py I still get the error:


blip@Terminus:~/git/tmdrv$ ./tmdrv.py -d thrustmaster_tmx
jscal: can't open joystick device: No such file or directory
jscal non-zero exit code 1, device may not be calibrated

@pastaq
Copy link
Contributor Author

pastaq commented Jul 26, 2017

I cleaned up those merges as requested.

@pastaq
Copy link
Contributor Author

pastaq commented Jul 26, 2017

Did a few time trials in GRID Autosport. There is a fairly significant dead zone on the wheel after jscal calibration was done. I only get left/right in the last 90* either direction. Makes for some quite entertaining driving.

Copy link
Owner

@her001 her001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your continued work on this! We are getting closer. The main problem is that jscal should not normally fail, so we need to figure out what is going on there.

Not a blocker, as I'd still accept it if I agreed with the change, but I prefer that unrelated changes are in separate commits.

README.md Outdated
- Ubuntu: sudo apt install joystick
- Other Distro's: compile from source from [Linux Console](https://sourceforge.net/projects/linuxconsole),
for calibration)

Copy link
Owner

@her001 her001 Jul 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree with this change.

  1. Nowhere else are there distro-specific instructions in the readme.
  2. It isn't my fault that some distros (not just Ubuntu) don't have the name of the software in the package name nor the description.
  3. Very few distros do not have Linux Console in their repositories; almost nobody will have to compile it if they don't want to.
  4. A minor point, but the new line at the end must be removed.

Maybe this can be worded in a different way. Something like:

* jscal (from [Linux Console](https://sourceforge.net/projects/linuxconsole), or
`joystick` in some distros' package repositories, for calibration)

Copy link
Contributor Author

@pastaq pastaq Jul 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to propose an alternative. Below the "Requirements" section of the readme could be an "Installation" section with instructions on how to install all dependencies for various distro's and set the udev rules. This will make the utility much more accessible as not everything is straightforward. Other people can then contribute to the Installation instructions for other distro's.
For example.

Installation

Ubuntu:
Install the dependencies:
sudo apt install python-libusb1 joystick git

Create the udev rules:
sudo echo "SUBSYSTEM=="'\""usb"\"", ATTRS{idVendor}=="\""044f"\"", MODE:="\""0666"\"", GROUP:="\""users"\""" >> /etc/udev/rules.d/10-local.rules
sudo udevadm control --reload
sudo udevadm trigger --action=add

Clone the repository:
git clone https://github.com/her001/tmdrv.git

Copy link
Owner

@her001 her001 Jul 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the readme could use better installation instructions, and your alternative is much more attractive, but I am not ready to accept such a change in this pull request. Please revert this change and open a separate issue where we can discuss this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in cc93365

{'step':2, 'request_type':0x41, 'request':83, 'value':0x0007, 'index':0x0000, 'data':b''},
]
jscal = '6,1,0,32505,32505,16574,2049063,1,0,519,519,1036399,1067305,1,0,512,512,1050596,1054724,1,0,511,511,1050596,1048544,1,0,0,0,536854528,536854528,1,0,0,0,536854528,536854528'
dev_by_id = 'usb-Thrustmaster_Thrustmaster_TMX_Racing_Wheel-joystick'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the device is not being found by jscal, maybe the dev_by_id is different after the wheel is initialized. As in, maybe the file name we have now is only valid for the uninitialized device. Could you look in /dev/input/by-id/ after running tmdrv to verify that the file is there with the same name?

Copy link
Contributor Author

@pastaq pastaq Jul 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just after a fresh hotplug it doesn't even show up in by-id until tmdrv is run. Perhaps jscal calibration is running before the symlink is made?


blip@Terminus:~/git/tmdrv$ ls /dev/input/by-id/
usb-046d_Logitech_Webcam_C930e_35FD9CCF-event-if00
usb-Blue_Microphones_Yeti_Stereo_Microphone_REV8-event-if03
usb-Corsair_Corsair_K70R_Gaming_Keyboard-event-if01
usb-Corsair_Corsair_K70R_Gaming_Keyboard-event-kbd
usb-Corsair_Corsair_K70R_Gaming_Keyboard-if02-event-kbd
usb-Logitech_USB_Receiver-if02-event-mouse
usb-Logitech_USB_Receiver-if02-mouse
usb-Valve_Software_Steam_Controller-event-mouse
usb-Valve_Software_Steam_Controller-mouse

blip@Terminus:~/git/tmdrv$ ./tmdrv.py -d thrustmaster_tmx
jscal: can't open joystick device: No such file or directory
jscal non-zero exit code 1, device may not be calibrated

blip@Terminus:~/git/tmdrv$ ls /dev/input/by-id/
usb-046d_Logitech_Webcam_C930e_35FD9CCF-event-if00
usb-Blue_Microphones_Yeti_Stereo_Microphone_REV8-event-if03
usb-Corsair_Corsair_K70R_Gaming_Keyboard-event-if01
usb-Corsair_Corsair_K70R_Gaming_Keyboard-event-kbd
usb-Corsair_Corsair_K70R_Gaming_Keyboard-if02-event-kbd
usb-Logitech_USB_Receiver-if02-event-mouse
usb-Logitech_USB_Receiver-if02-mouse
usb-Thrustmaster_Thrustmaster_TMX_Racing_Wheel-event-joystick
usb-Thrustmaster_Thrustmaster_TMX_Racing_Wheel-joystick
usb-Valve_Software_Steam_Controller-event-mouse
usb-Valve_Software_Steam_Controller-mouse

Copy link
Contributor Author

@pastaq pastaq Jul 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional feedback. I wanted to further test my hypothesis about the symlink. In tmdrv.py I replaced lines 49, 50 with a pass and commented 64-71 after I ran tmdrv to init the device. This essentially should only run the jscal line of code. On the second run, bypassing this usb error, the jscal data loads fine.

Using the normal code I tried a few times doing a rapid succession of ls -al in the by-id directory and it doesn't appear until after the script has errored on the jscal line. I'm not sure how to tail for directories adding a symlink to the the exact moment.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I understand the issue now. Should be fixed by dfe9643.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pulled from upstream to test this change. It doesn't seem to have fixed the issue. I added a print(handle) at line 71 just before connected=true. Both handles from step 1 and 2 initialize and the handle populates, but the jscal line still runs before the symlink populates. I crudely added a sleep(5) and it resolved the issue entirely, which works but obviously isn't the best method. I'd like to have a more technical answer to be honest. I suspect that the device sends some sort of URB type message to the system that it has completed initialization perhaps. I looked around in the pcap data and there are some interesting packets around 966, but I have very little understanding of what is actually happening in them.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually just working on a better fix. See 5e59ee8. Please tell me if it works, but either way, I do not consider this a blocker to this pull request.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That solved it. Working as expected now. Do you want me to push the fix for the merge conflicts?

Copy link
Owner

@her001 her001 Jul 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will also need to fix the whitespace, as I mentioned in a later review, and test that the jscal data is giving you a good calibration (the deadzones are eliminated and everything works as expected).

After that, fixing the merge conflicts should be all that remains.

@her001
Copy link
Owner

her001 commented Jul 26, 2017

It is unusual that jscal is giving such bad values. Having a large deadzone in the center of the wheel, but everything else working fine, is what would be expected if no calibration was done at all. You can try running it again (maybe a few times) until you get better results, or try to manually tweak the jscal configuration.

- Removed README.md instructions modifications as requested.
Copy link
Owner

@her001 her001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once this is done, all we need to do is make sure that jscal is actually calibrating this device correctly.

README.md Outdated
@@ -25,7 +25,8 @@ See the status of additional devices on
* [Python 3](https://www.python.org)
* [python-libusb1](https://pypi.python.org/pypi/libusb1)
* jscal (from [Linux Console](https://sourceforge.net/projects/linuxconsole),
for calibration)
for calibration)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the extra space and new line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woops, fixed.

@pastaq
Copy link
Contributor Author

pastaq commented Jul 27, 2017

Just tested in GRID Autosport again and it seems to be working as intended. Axes were calibrated correctly.

@her001 her001 merged commit 9bc1451 into her001:master Jul 27, 2017
@her001
Copy link
Owner

her001 commented Jul 27, 2017

Thanks for your contribution and patience during the review!

@pastaq pastaq deleted the tmx-ff branch December 6, 2023 01:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants