jfedor2 / magellan-spacemouse

Adapter to use RS-232 Magellan/SpaceMouse with modern software
37 stars 8 forks source link

Request to create firmware for space mouse classic usb #1

Open Platidors opened 1 year ago

Platidors commented 1 year ago

Hello. I assembled hid-remapper for your project on one raspberry pi pico board. Tried connecting my old Space Mouse Classic USB controller. On some computers, the Space Mouse Classic USB is not installed correctly. I tried with the help of your device to solve this problem. Space Mouse certainly didn't work with hid-remapper. I want to ask you to make Space Mouse Compact emulation firmware for Space Mouse Classic USB based on the hid-remapper board. Ready to become a firmware tester.

photo_2023-03-08_22-54-15

photo_2023-03-08_22-56-41

photo_2023-03-08_22-56-51

Platidors commented 1 year ago

I'll try to find Space Mouse Pro and ask them to send a descriptor report

Platidors commented 1 year ago

I noticed that pressing the buttons from 1-8 causes a slight movement of the axis. This is not a big problem, but in sketch mode it can get in the way a bit. Can this be fixed somehow?

jfedor2 commented 1 year ago

I'm guessing this is a physical thing, pressing the buttons causes some tiny readings on the sensors because the case flexes a bit or something like that.

You can try setting a dead zone, I believe on this model it can be done on device side by pressing "*"+"7" buttons. You can also set a dead zone in HID Remapper using expressions, that is a bit more involved, but nothing crazy. There are examples in the docs.

Platidors commented 1 year ago

"*"+"7" combination fails to set zero radius. It seems to me that this bug is not of a physical nature.

Platidors commented 1 year ago

image Maybe the buttons at the bottom with addresses have something to do with it?

Platidors commented 1 year ago

Found a programming manual. Maybe you've already seen it, but still https://www.manualslib.com/manual/1994332/Logitech-Magellan-Space-Mouse-Classic.html#manual

Platidors commented 1 year ago

Space Mouse Pro SpaceMouseProUSBHook.zip

jfedor2 commented 1 year ago

Thank you!

0x00090009 and 0x0009000c are buttons 9 and 12, they're in the descriptor, but the device doesn't even have that many. I guess maybe "*" is one of them, but I don't know if it's even sent to the host as it is used for device-side configuration (easy to test).

Platidors commented 1 year ago

May I hope for an emulator firmware based Space Mouse Pro?

jfedor2 commented 1 year ago

Yeah, try this!

remapper_spacemouse9.zip

It also includes a different fix for the split reports issue so you need to flash both A and B sides. Let me know if there's any issue.

The buttons will need to be mapped.

The Classic has the following buttons:

1, 2, 3, 4, 5, 6, 7, 8, 9, 12

The Pro has the following:

1, 2, 3, 5, 6, 9, 13, 14, 15, 16, 23, 24, 25, 26, 27

Platidors commented 1 year ago

There were a lot of buttons with obscure addresses

image

Platidors commented 1 year ago

Buttons with addresses do nothing. The rest of the buttons are reassigned normally. The axes seem to work correctly, but you have to swap them as before. Pressing the buttons still slightly move the joystick in 3D view.

Platidors commented 1 year ago

Button functions Space Mouse Pro 1 - MENU 2 - Fit 3 - TopV 5 - RightV 6 - FrontV 9 - Roll+ 13 - 1 14 - 2 15 - 3 16 - 4 23 - Esc 24 - Alt 25 - Shift 26 - Ctrl 27 - LockR

Space Mouse Classic USB 1 - 1 2 - 2 3 - 3 4 - 4 5 - 5 6 - 6 7 - 7 8 - 8 9 - *

Platidors commented 1 year ago

Different behavior in the test program 3DxTest.exe. Coordinates don't reset to zero

https://user-images.githubusercontent.com/127308740/225426936-562e20cb-b2b9-432f-8944-0d0431da508f.mp4

https://user-images.githubusercontent.com/127308740/225426946-18ab47a1-6ed1-4551-bb4f-8924692825db.mp4

jfedor2 commented 1 year ago

Different behavior is possibly caused by the fact that the axes are relative in the Pro's report descriptor. While as I said I think this is incorrect, it also means that it doesn't have to send zeros when the movement stops, just like a normal 2D mouse doesn't.

You can dump the SpaceExplorer's report descriptor to see if the usages are absolute in there.

As for the buttons causing movement, I don't have any new ideas, you can try connecting the Pro Classic directly to the PC and capturing traffic with Wireshark while pressing buttons and not moving the joystick. Then we can try to see if it looks like random noise or some protocol misinterpretation.

The 0xFF00... usages are vendor-specific, who knows what they're for.

Platidors commented 1 year ago

I'll try when I get home. Could you help me to set the deadzone through the Expression settings. At least approximate values and code format?

Platidors commented 1 year ago

You can dump the SpaceExplorer's report descriptor to see if the usages are absolute in there. SpaceExplorer.zip

Platidors commented 1 year ago

As for the buttons causing movement, I don't have any new ideas, you can try connecting the ~Pro~ Classic directly to the PC and capturing traffic with Wireshark while pressing buttons and not moving the joystick. Then we can try to see if it looks like random noise or some protocol misinterpretation. SpaceMouseClassicKey.zip Pressed 1 2 3 4 5 6 7 8 9 *

jfedor2 commented 1 year ago

Well, it really is sending those axis inputs, I don't see any "logical" pattern there or anything that would suggest it's the remapper's fault.

To configure dead zones, first set up six expressions, one for each axis.

You have to use the following hex codes:

0x00010030: X 0x00010031: Y 0x00010032: Z 0x00010033: RX 0x00010034: RY 0x00010035: RZ

Each expression will look the same, only the hex code will be different. Of course you can also set the dead zone per-axis if you want.

For example let's say Expression 1 will be for axis X:

0x00010030 input_state dup abs 10 gt mul scaling mul

It's explained in detail here:

https://github.com/jfedor2/hid-remapper/blob/master/EXPRESSIONS.md

But basically we're fetching the axis state, duplicating it, taking its absolute value, checking if it's greater than 10 or not (this is the dead zone), which gives either a 0 or a 1, multiplying it by the original value, leaving us with either zero if it was inside the dead zone or the original value if it was not. At the end we fetch the scaling value from the mapping and multiply by it. That way you can set the axis inversions as before.

Assuming you configured Expressions 1-6 this way:

Screenshot from 2023-03-17 00-01-06

You can then configure the mappings like so:

Screenshot from 2023-03-16 23-56-50

And in theory it should work.

jfedor2 commented 1 year ago

Here's a JSON with the above configuration.

spacemouse-deadzones.zip

jfedor2 commented 1 year ago

It would also be possible to program it to ignore axis inputs when a button is pressed.

Platidors commented 1 year ago

The filter seems to be working well. Pressing the buttons does not lay down the axes. It is enough to filter the axes RX, RY, RZ. Maybe there is a way to return the movement data to 0 when there is no action on the joystick?

jfedor2 commented 1 year ago

Is this a problem in practice? In real software?

Platidors commented 1 year ago

It is not possible to move the center of rotation of an object in solidworks. The space mouse cursor does not move over the part, but is always in the center

jfedor2 commented 1 year ago

I'm not familiar with Solidworks. Is that related? How did you expect it to work?

Platidors commented 1 year ago

When the coordinates of all axes are set to 0, the space mouse cursor is released and moved to the part in the center of the screen on another part of the part. This allows it to rotate around the new center. You seem to intercept the part with your hand when you move it. I have interesting news. I tried connecting the space guide to the HID-remapper and it worked. The HID-remapper turns out to be a universal device. In the 3DxTest program, the coordinates are also not returned to 0.

jfedor2 commented 1 year ago

Oh, I see!

Yeah, it should be possible to make it send zeros, let me think how to do it best.

And yeah, HID Remapper was originally built to map anything to anything. :) The original one emulates mouse and keyboard so the output needed to be modified, but on the input side we pretty much support anything. You could connect a flight sim joystick or a game pad and use it as a 3D mouse, assuming you set up the mappings in some reasonable way.

(Well, that's not entirely true, the current version limits the report size to 14 bytes, but that's just a quick hack to handle the SpaceMouse Classic's reports being split into two packets, it could be fixed properly to work with any report size.)

jfedor2 commented 1 year ago

This should send zeros after the movement stops and hopefully not break anything else:

remapper_spacemouse10.zip

(The B side didn't change, I just included it for completeness.)

Platidors commented 1 year ago

It works, but not always. RX, RY, RZ get up to 0 always, TX, TY, TZ get up to 0 sometimes. In solidworks cursor moves but not every time you release the joystick

https://user-images.githubusercontent.com/127308740/226142321-cc9bc208-fa1b-47d1-9cf3-9c564fc6a278.mp4

dead zones included on all axes

jfedor2 commented 1 year ago

Interesting.

I took a closer look at what my SpaceMouse Compact sends and noticed two things. First, even though the translations and rotations are separate report IDs, it always sends them in pairs. Second, when the movement stops, it actually sends the all-zero reports three times.

I should probably try to emulate at least the first thing.

Platidors commented 1 year ago

Perhaps in this way 3dconnexion tried to protect its manipulators from copying

jfedor2 commented 1 year ago

OK, this should always send the axes reports in pairs.

remapper_spacemouse11.zip

Platidors commented 1 year ago

On this firmware, the space mouse works great. In all programs, the movements became smooth. In the 3DxTest program, all coordinates go to 0 after releasing the joystick. In the solidworks program, the cursor moves well. I still use your filters to set dead zones for all axes. And it works fine. Without them, false positives of the joystick appear when a key is pressed. This is apparently the specifics of the old matipulators. I tried to connect a modern space explorer. On this firmware, the joystick is not processed very well, intermittent movements are noticeable. So this firmware is not universal for all space mouse. Video when connecting the space explorer.

https://user-images.githubusercontent.com/127308740/226259257-efa7f1dd-0aa4-42f0-9da3-930747c345f7.mp4

jfedor2 commented 1 year ago

Yeah, this is probably because we're now sending two reports for every received motion report and the Explorer, unlike the Classic, sends the translations and rotations in separate reports. So for the Explorer, every time we receive a X,Y,Z report, we send a (normal) X,Y,Z report and a (zero) RX,RY,RZ report and for each RX,RY,RZ report we send a (zero) X,Y,Z report and a (normal) RX,RY,RZ report.

My goal was to make it universal and a minimal modification of the regular HID Remapper, but it turned out a few device-specific hacks were necessary. Maybe I will find a way to make it more generic in the future.

Platidors commented 1 year ago

In the rs-232 space mouse Maggelan version of the emulator, there are no such problems as double reporting, turning the joystick when pressing the buttons, not returning the coordinates to 0?

jfedor2 commented 1 year ago

The Magellan adapter doesn't use HID Remapper as a base, it's much simpler code that just happened to avoid those issues, even though I wasn't aware of them at the time.