usatenko / DjiMini2RCasJoystick

Python Linux uevent virtual joystick interface for DJI Mini 2 RC (also known as RC-N1, RCS231, WM161b-RC-N1, RCN1) <-> Linux joystick interface (uinput)). Inspired by hjstn/miniDjiController
Apache License 2.0
37 stars 6 forks source link

Support for buttons #2

Closed martonmiklos closed 7 months ago

martonmiklos commented 10 months ago

Hi all!

Would it be possible to add support for buttons?

I dumped the data array for the periodic DUML query, but the button presses does not alter it. Do you have any information how the analog messages DUML command was figured out? Using the DJI Simulator and sniffing the serial traffic, or it was done on the Android app?

usatenko commented 9 months ago

interesting, honestly, I do not remember why I did not take the data for buttons, I will check and update here

martonmiklos commented 9 months ago

Yeah in the meantime I looked after the DJI simulator, and the Mini2 remote is not supported in it. Interestingly there are folks out there who simulate XBox game controller based on the reverse engineered protocol šŸ¤£

usatenko commented 9 months ago

yes, the simulator does not support it, this is why it needs to be manually switched to a data reading mode. XBox controller is just a different option of joystick, can be simulated also I believe (in case it will be possible to read the buttons...)

Pixxxxel commented 7 months ago

Hello!

I've been trying to get button information from the remote as well. It looks like the byte array which is returned does not contain anything about buttons. All the known commands ("get info" and "simulator mode enable") have the same cmd_type and cmd_set. Do you think it will be a good idea to try 254 other cmd_ids on these cmd type and set in order to find out if button information could be requested by any of them or i have a large chance to brick my remote?

martonmiklos commented 7 months ago

Well I would still try to figure out that how did these DUML commands figured out. By reverse engineering the firmware of the app itself?

Pixxxxel commented 7 months ago

If we look back in history, yes, the first set of bytes was found by looking at remote and dji app talk. Here is the link https://github.com/Matsemann/mDjiController/issues/3

However i have no idea who came up with send_duml method and how they found out which bytes are responsible for all the stuff. But the classification seems pretty correct. Also the protocol changed a lot for rc-n1 as mDjiController has incredibly different messages (AND THEY HAVE BUTTONS!!)

martonmiklos commented 7 months ago

If we look back in history, yes, the first set of bytes was found by looking at remote and dji app talk. Here is the link Matsemann/mDjiController#3

However i have no idea who came up with send_duml method and how they found out which bytes are responsible for all the stuff. But the classification seems pretty correct. Also the protocol changed a lot for rc-n1 as mDjiController has incredibly different messages (AND THEY HAVE BUTTONS!!)

Do you know if the button presses are detectable somehow by the Android app? maybe we could route the serial port with a gadget OTG driver with some Linux board and could sniff the serial traffic.

Pixxxxel commented 7 months ago

Oh, that's a good question. I know there is (maybe the only) simulator-like game on android called simuDrone and it isn't able to detect buttons. However, if we look at flight logs, at least we have info about cine / normal / sport profile. But it's hard to say either this information is from controller or from the drone

martonmiklos commented 7 months ago

Oh, that's a good question. I know there is (maybe the only) simulator-like game on android called simuDrone and it isn't able to detect buttons. However, if we look at flight logs, at least we have info about cine / normal / sport profile. But it's hard to say either this information is from controller or from the drone

I jumped on the Android bandwagon lately and I do not have OTG cable yet, but in the DJI GO app there is not anything like remote test or something?

Pixxxxel commented 7 months ago

I use dji fly with my mini 3 and i haven't seen such features in this app

Pixxxxel commented 7 months ago

There is another repository where send_duml is used. I'd really want to ask the creator of this method a couple of questions and probably it's either usatenko or IvanYaky https://github.com/IvanYaky/DJI_RC-N1_SIMULATOR_FLY_DCL

Upd: nvm, this is likely the original solution

Pixxxxel commented 7 months ago

If we look back in history, yes, the first set of bytes was found by looking at remote and dji app talk. Here is the link Matsemann/mDjiController#3 However i have no idea who came up with send_duml method and how they found out which bytes are responsible for all the stuff. But the classification seems pretty correct. Also the protocol changed a lot for rc-n1 as mDjiController has incredibly different messages (AND THEY HAVE BUTTONS!!)

Do you know if the button presses are detectable somehow by the Android app? maybe we could route the serial port with a gadget OTG driver with some Linux board and could sniff the serial traffic.

I think i found something related to dji traffic parsing. Have a look at this https://wiki.dji-rev.com/howto/dumlprinter

We use "ACK" (whatever it is) type command from "Remote Control" command set

martonmiklos commented 7 months ago

We are likely using the 'RC Simulate Flight Mode Set' for enable (0x24) and the 'RC Channel Params Get' for polling: https://github.com/o-gs/dji-firmware-tools/blob/master/comm_dissector/wireshark/dji-dumlv1-proto.lua#L132

There are some other commands code which might be useful to poke with.

Pixxxxel commented 7 months ago

We are likely using the 'RC Simulate Flight Mode Set' for enable (0x24) and the 'RC Channel Params Get' for polling: https://github.com/o-gs/dji-firmware-tools/blob/master/comm_dissector/wireshark/dji-dumlv1-proto.lua#L132

There are some other commands code which might be useful to poke with.

Wow, that's an amazing piece of information! Thank you! Unfortunately, the description of commands doesn't sound like something we need. Only "[0x04] RC Physical Channel Parameter Get" caught my attention, but that can be just anything else. Worth a try anyway.

Pixxxxel commented 7 months ago

So i tried a couple of commands and here are the results:

So far i've ran out of ideas what else to try but the comment to 0x48 is a bit suspicious

martonmiklos commented 7 months ago

We are likely using the 'RC Simulate Flight Mode Set' for enable (0x24) and the 'RC Channel Params Get' for polling: https://github.com/o-gs/dji-firmware-tools/blob/master/comm_dissector/wireshark/dji-dumlv1-proto.lua#L132 There are some other commands code which might be useful to poke with.

Wow, that's an amazing piece of information! Thank you! Unfortunately, the description of commands doesn't sound like something we need. Only "[0x04] RC Physical Channel Parameter Get" caught my attention, but that can be just anything else. Worth a try anyway.

Well keep in mind that the file was committed last time 3 years ago when I am unsure if the RC-N1 even existed. I do not know how were these things got acquired, but I think it was done by analyzing the firmwares.

Pixxxxel commented 7 months ago

Well keep in mind that the file was committed last time 3 years ago when I am unsure if the RC-N1 even existed. I do not know how were these things got acquired, but I think it was done by analyzing the firmwares.

I don't know much about all the dji products, but some of the quads with rc-n1 were presented in 2020. (mini 2, air 2). As far as the commands seem to work flawlessly, i guess they perfectly suit us (if we look at https://github.com/hjstn/miniDjiController/blob/master/main.py which is for mini 1, the codes are not the same and neither they were for older phantoms).

My guess is that we either miss something or it is impossible to get button trigger info and i can't really think of a way to make remote interact with software when it'll give button information (other than the way you suggested with smartphone, but that's too complicated for me).

usatenko commented 7 months ago

The only thing that can be read so far is a roller wheel at the left side

usatenko commented 7 months ago

Good news, I found it. The button values are under command 27.

image image
usatenko commented 7 months ago

For example the answer of this duml packet with "Fn" button pressed and released is: image

usatenko commented 7 months ago

Top right button: image

Just need some time to implement it.

usatenko commented 7 months ago

The change is implemented, all 4 buttons can be used with a joystick. https://github.com/usatenko/DjiMini2RCasJoystick/commit/1c2e6f3e3eb363ee01f2e9b61305bd6d3a57c72d I am not sure I used right names of buttons, I can change if you tell me the correct names, though I believe they can be mapped in a simulator. Current mappings are:

Let me know if there are any issues.

UPD: The central switcher also added.

Pixxxxel commented 7 months ago

Great job! Iā€™m a little jealous I havenā€™t discovered that yesterday, Iā€™ve tried bunch of other commands, but not 0x27 :)

Iā€™ve seen the left big button referred as ā€œgo_home_buttonā€ in the file with command list.

usatenko commented 7 months ago

Iā€™ve seen the left big button referred as ā€œgo_home_buttonā€ in the file with command list.

I mean I am not sure which standard joystick buttons should be mapped to these RC buttons. They all listed here: https://docs.huihoo.com/doxygen/linux/kernel/3.7/include_2uapi_2linux_2input_8h.html