-
Notifications
You must be signed in to change notification settings - Fork 12
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
Conversation
- ./tmdrv.py -d thrustmaster_tmx_ff results ins normal initialization.
TMX Force Feedback and TMX Pro are the same device, packaged with different pedals.
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:
|
There was a problem hiding this 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.
tmdrv_devices/thrustmaster_tmx.py
Outdated
@@ -0,0 +1,9 @@ | |||
name = 'Thrustmaster TMX' | |||
idVendor = 0x044f | |||
idProduct = [ 0xb65d, 0xb67e] |
There was a problem hiding this comment.
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.
tmdrv_devices/thrustmaster_tmx.py
Outdated
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''}, |
There was a problem hiding this comment.
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.
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 During handling of the above exception, another exception occurred: Traceback (most recent call last): Traceback after the fix: blip@Terminus:~/git/tmdrv$ sudo ./tmdrv.py -d thrustmaster_tmx output of /dev/by-id: blip@Terminus:~/git/tmdrv$ ls -al /dev/input/by-id/ my udev rule from /etc/udev/rules.d/10-local.rules: SUBSYSTEMS=="usb", ATTRS{product}=="Thrustmaster FFB Wheel", GROUP="users" |
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 As for your udev rules, you may want to change it to something like:
If this works properly, you should be able to run everything without needing extra permissions. |
tmdrv_devices/thrustmaster_tmx.py
Outdated
{'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' |
There was a problem hiding this comment.
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.
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 |
I cleaned up those merges as requested. |
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. |
There was a problem hiding this 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) | ||
|
There was a problem hiding this comment.
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.
- Nowhere else are there distro-specific instructions in the readme.
- 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.
- Very few distros do not have Linux Console in their repositories; almost nobody will have to compile it if they don't want to.
- 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)
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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' |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
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.
There was a problem hiding this 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) | |||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woops, fixed.
Just tested in GRID Autosport again and it seems to be working as intended. Axes were calibrated correctly. |
Thanks for your contribution and patience during the review! |
./tmdrv.py -d thrustmaster_tmx_ff results in normal initialization.