meekworth / pylwdrone

Python module to communicate with a lewei camera module.
Apache License 2.0
19 stars 4 forks source link

any idea how to extract GPS, compass and altitude data from eachine ex5 #6

Open deltamelter opened 2 years ago

deltamelter commented 2 years ago

Got one of these more advanced toys with GPS and barometric compass. the app seems to be the same lewei_cmd based device with traffic or at least listening on ports 7060,8060,9060 and 50000. There is no sdcard in the drone and the board lw_10015 v22 doesn't appear on the lewei website. took a pcap from the phone app and will be great to grab the video and stills from the stream but even better to add the geolocation details and log a GPS flight path. I imagine the gps data is somehow encoded into tcp packet bytes, just not sure how... Any ideas?

hieyou1 commented 2 years ago

Send a pcap if possible?

deltamelter commented 2 years ago

Send a pcap if possible?

will need to capture smaller pcap with just app traffic. pylwdrone works with basic streaming and pic grab but other options throw timeout exceptions

hieyou1 commented 2 years ago

Gotcha. I don't have hardware like that so pcap would be required to figure out how to parse your bytes, however this may reveal your geolocation, so maybe try and do some basic detection (find out your GPS coordinates and filter them from the pcap if they appear) and make sure to pcap in a public place.

pylwdrone works with basic streaming and pic grab but other options throw timeout exceptions

Can I take a look at the "other options" and the timeout exceptions that you get by providing those options? I may be able to help with that without using a pcap

hieyou1 commented 2 years ago

Also, if you could send over a link to your app that'd be great, because I may be able to decompile it [if it's on Android] to see what I can find without the pcap. No promises with that though; decompiling apps is time-consuming and may not garner any results

deltamelter commented 2 years ago

Eachine Pro 1.6.0 https://play.google.com/store/apps/details?id=com.lwcx.lw061 looked inside but I guess the important bits are compiled into so files

deltamelter commented 2 years ago

Gotcha. I don't have hardware like that so pcap would be required to figure out how to parse your bytes, however this may reveal your geolocation, so maybe try and do some basic detection (find out your GPS coordinates and filter them from the pcap if they appear) and make sure to pcap in a public place.

Yeah, I've looked, but I don't know the format the coordinates are stored in, might be as large integer and N/S E/W is usually just positive or negative. The app displays the longi- and latitude as an integer (incorrectly leaving minus) eg N61.0123456 W-7.0123456 Also shows Altitude, Distance, Speed V, Speed H, num of Sats, Roll, Pitch and Yaw. These values are quite erratic so not so easy to know what to expect to see in the tcp dump.

hieyou1 commented 2 years ago

Eachine Pro 1.6.0 play.google.com/store/apps/details?id=com.lwcx.lw061 looked inside but I guess the important bits are compiled into so files

Yep, decompiled using jadx and could not find anything, lots of either obfuscated or incorrect code and references to other directories. Someone else can try their hand since I'm not that experienced with Java if they want to.

Got one of these more advanced toys with GPS and barometric compass. the app seems to be the same lewei_cmd based device with traffic or at least listening on ports 7060,8060,9060 and 50000. There is no sdcard in the drone and the board lw_10015 v22 doesn't appear on the lewei website. took a pcap from the phone app and will be great to grab the video and stills from the stream but even better to add the geolocation details and log a GPS flight path. I imagine the gps data is somehow encoded into tcp packet bytes, just not sure how... Any ideas?

Could you get any functionality of pylwdrone to work with your drone? If not, can you take a look at your pcap and see if there's a UDP stream at 50000 that seems to conform to this JS? If not, could you fly your drone around for a bit and send a filtered pcap of only port 50000? Lewei drones only use this port for controls so this shouldn't include any sensitive data.

deltamelter commented 2 years ago

Could you get any functionality of pylwdrone to work with your drone? If not, can you take a look at your pcap and see if there's a UDP stream at 50000 that seems to conform to this JS? If not, could you fly your drone around for a bit and send a filtered pcap of only port 50000? Lewei drones only use this port for controls so this shouldn't include any sensitive data.

Yes, pylwdrone worked with baud, pic,pic2, stream, config get, all worked but time, heartbeat and res returned exceptions, mostly timeout. time command actually returns OverflowError: timestamp out of range for platform time_t maybe the version I'm using in wsl?

Too windy to fly right now and no space indoors but sat it outside and let it find satellites then took pcap and did screen record with timestamp so I could try to see if any packets coincided with the changing GPS coords. but there is still a lot of video stream traffic and I can't tell the difference between vid and data

I didn't do anything with the app but it still sends packets to 50000/udp 68010d80808080200802000c000000002a Is this somekind of heartbeat? or could response be data? gyro, GPS or so? mostly the 50000 response is 18 bytes long, tho sometimes 17 or 12 Do you have detail on the 50000 responses structure? UDP, Src Port: 51835, Dst Port: 50000 68 01 0d 80 80 80 80 20 08 02 00 0c 00 00 00 00 2a

UDP, Src Port: 50000, Dst Port: 51835 mostly 18 byte response starting 58 8b handful of 17 byte responses starting 58 8c a small number of 12 responses starting 58 8f

hieyou1 commented 2 years ago

Haven't had time to look at this in depth yet, I will soon. In the meantime could you please send over your "config get" if it's working? Thanks!

Edit: By the way, if it ends up being gyro/gps/etc, I won't be able to help as I don't have those values to begin with (and I respect your privacy so I will not attempt to seek them). What I'm going to do once I have time is take a look at the difference between what the control library is sending and the byte you sent me. If you have the other two byte types (12 and 17) that would be helpful as well- thanks!

deltamelter commented 2 years ago

Is config get supposed to show more? $ pylwdrone config get Camera flip: up WiFi Channel: 36 WiFi Security: open WiFi Name: WiFi Password: 12345678 SD card ready: False SD card size: 0 MiB SD card free: 0 MiB Version: V300 Current time: 1970-01-01 01:00:00 success btw Just did a quick pcap indoors where GPS shows as N0, W0 and there are chunks of the 50000 response that are 00 and 00000000 but filled when I did pcap outside with gps lock. trying to decipher how these might contain a representation of the actual coords, but might still be a goose chase

hieyou1 commented 2 years ago

Can confirm that the control is not the same.

The message structure as defined in tjhorner's blog post (good reading, by the way):

Hex-encoded version of the basic "no command" from TJ's library: 6680808080000099 (conforms to above spec)

However yours (68010d80808080200802000c000000002a) does not appear to conform to the above spec. The fact that there is 80808080 after the apparent prefix of 68010d may or may not coincide with movement and throttle, however that leaves 200802000c000000002a left to be decoded later.

but there is still a lot of video stream traffic and I can't tell the difference between vid and data

On port 50000? If it's on a different port (and you're using Wireshark) you can filter what packets you view using this syntax:

udp.dstport == 50000 || udp.srcport == 50000

Hope that helps a bit.

Do you have detail on the 50000 responses structure?

I've never looked into it-- it hasn't been important for my drone's control, I can take a look if I have the responses.

Is config get supposed to show more?

No, that looks good. Probably won't be helpful but every little bit of info counts

btw Just did a quick pcap indoors where GPS shows as N0, W0 and there are chunks of the 50000 response that are 00 and 00000000 but filled when I did pcap outside with gps lock. trying to decipher how these might contain a representation of the actual coords, but might still be a goose chase

Can you send the full "zeroed" response? Edit: Could you also mention which bytes "change" when you go outside, and see if they correspond at all to lat/lng/gyro/etc?

hieyou1 commented 2 years ago

Further taken apart:

68010d80808080200802000c000000002a

deltamelter commented 2 years ago

Found the GPS coords :grin: , hadn't spotted because they are encoded little-endian 32bit signed in the 17byte 50000/UDP response

I'll see if I can work out what's in the 12 and 18 byte responses...

hieyou1 commented 2 years ago

Does 12-16 correspond with compass or gyro at all?

deltamelter commented 2 years ago

Does 12-16 correspond with compass or gyro at all?

Don't know, it never changes. 03e8 = 1000 which may somehow relate to the range limit. I think it has some kind of geowall to restrict flying out of range. but just guessing 😀

Looks like the 18 byte response relates to gyro. just not exactly sure how the number are formatted... they are close to what I see in the app but didn't see the exact combination, but probably the app doesn't refresh as often as these are received ( like every millisecond)

588b - header 0e - data len ec20 - roll (-180 to +180) /100 = 84.28 d6fe - pitch (-180 to +180) /100 = -2.98 6ff8 - yaw (-180 to +180) /100 = -19.37 df80250000000007 - didn't figure this bit out yet, changes a lot 8b checksum

deltamelter commented 2 years ago

was trying to figure out how to stream these 50000/udp responses so I could see how they change realtime in reaction to drone position. should be something that pylwdrone could do, right?

hieyou1 commented 2 years ago

should be something that pylwdrone could do, right?

This is (probably) outside the scope of this mainly camera-based library however I could modify or create a library to parse these responses, probably in Node since there is an existing library that already communicates with the drone written in Node.

deltamelter commented 2 years ago

not really used node.js too much, I wasn't able to find and examples of UDP receiving packets like this. Seems like all the other dronelibs send commands on UDP but don't care about responses or incoming packets. would be interested in seeing how you do it.

Would quite like to add geolocation and gyro exif data to captured images like the big boys do... 😀

deltamelter commented 2 years ago

figured out the rest of the data... GPS lat/long, satellite locks, altitude, distance, Vspeed, Hspeed, gyro (yaw/pitch/roll), battery. now creating an android app to log the data and tie it to JPEGs/exif

deltamelter commented 2 years ago

I realise this is not much interest to those whose drones don't do GPS, but also worked out how to send the drone a series of waypoints (lat, long and altitude and how long to stay there before continuing to next point) command is 6804.... The app can send up to 30, but not sure how many the drone can handle at once. Altitude say's it is in feet, but like everything else with this app, it's actually meters Also found the "follow me" feature which sends the GPS coords of the phone to the drone and and the drone flys towards it at same altitude, command is 6802... Lastly the Orbit command (6803...) which sends the coords of the phone and the drone does some moves, eventually flying around the phone at a random (it seems) distance.

kdudkov commented 1 year ago

figured out the rest of the data... GPS lat/long, satellite locks, altitude, distance, Vspeed, Hspeed, gyro (yaw/pitch/roll), battery. now creating an android app to log the data and tie it to JPEGs/exif

could you share that knowledge?

deltamelter commented 1 year ago

could you share that knowledge?

I didn't look at the data in a while. What drone you got? is it EX5 or other GPS drone? what did you want to know?

kdudkov commented 1 year ago

could you share that knowledge?

I didn't look at the data in a while. What drone you got? is it EX5 or other GPS drone? what did you want to know?

LLC SG907MAX, GPS drone, message format looks the same

message examples:

0x8a - ? "\x58\x8a\x0c\x58\x4c\x30\x31\x32\x53\x46\x58\x78\x80\x0c\x08\x10"

0x8b pitch, roll, yaw "\x58\x8b\x0e\x39\x00\xf3\x00\x7e\x3d\xfb\x00\x29\x00\x00\x00\x00\x07\xd9"

0x8c - lat, lon "\x58\x8c\x0d\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x6a"

0x8f - electromagnetic field value? "\x58\x8f\x08\xc0\xf0\x0c\x00\x00\x01\x00\x00\xba"

0xfe - text (device model) "\x58\xfe\x19\x48\x46\x2d\x58\x4c\x2d\x58\x4c\x30\x31\x32\x53\x30\x31\x31\x2e\x30\x32\x31\x2e\x31\x32\x32\x32\x05\x8c"

kdudkov commented 1 year ago

https://github.com/kdudkov/drone_logger/blob/master/messages.md

deltamelter commented 1 year ago

mine doesn't use 0x8a or of 0xfe 0x8f has voltage, but you found that already I see in messages.md I took pcap on the phone while doing screen recorder with the drone app and displaying the unix timestamp then searched the pcap for the timestamps when the data changed on app screen. Most data is slow enough to see the exact value pop up, except 0x8b (yaw,roll,pitch) which get averaged out over several samples.

deltamelter commented 1 year ago

0x8a - ? "\x58\x8a\x0c\x58\x4c\x30\x31\x32\x53\x46\x58\x78\x80\x0c\x08\x10"

Oh, 0x8a is only at startup on mine...
58 8a 09 JYEX5XFXx 60 09 08 e2

deltamelter commented 1 year ago

0x8c - lat, lon "\x58\x8c\x0d\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x6a"

@kdudkov 0x8c - coords <Buffer 58 8c 0d 62 fe ec ff 11 62 b2 1e a8 07 4d 02 d9 e8> 58 8c 13 lat -0.1245598 lon 51.5006993 altitude(m) 96 distance(m) 123.2 vSpeed 0.1 hSpeed -3.9 e8

1 58 header 2 8c message type 3 0d payload len 4-7 62feecff longitude10000000 32bit signed int (LE) 8-11 1162b21e latitude10000000 32bit signed int (LE) 12-13 a80 - Altitude in meters /10 starting at 1000m at ground level (& 0x7ff)-0x3e8)/10 16bit signed int (LE) 13-14 74d - Distance from receiver (meters) >>4 /10 16bit signed int (LE) 15 02 vertical speed >>1 /10 8bit signed int (LE) 16 d9 horizontal speed /10 8bit signed int (LE) 17 e8 checksum

The default app says ft, but it IS ALL in Meters. I captured from video+pcap on a measured 100m sport field There might be a way to read the altitude and distance without bitshifting and masking, but this worked for me

never used golang before, but seems to work same way... app.info.put("alt", float64(int32(binary.LittleEndian.Uint16(msg[11:13])-1000&0x7ff))/10) app.info.put("distance", float64(int32(binary.LittleEndian.Uint16(msg[12:14])>>4))/10)

nobu835 commented 1 month ago

I also have a similar drone, and I was wondering how to calculate the checksum, so I looked it up. After 8 hours of thinking, I finally found the simple formula. I hate myself for not realizing it sooner.

Exclude the first 0x58 or 0x68, and arrange the rest of the byte sequence as a bit sequence. Bits with an odd number of 1s are set to 1, and bits with an even number are set to 0, and that is the checksum. For example, \x58\x8c\x0d\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x6a is

58 skip 8c 1000 1100 0d 0000 1101 e8 1110 1000 03 0000 0011 = 0110 1010 = 6a.

nobu835 commented 4 weeks ago

I'm using "HS GPS V4" app is here: https://play.google.com/store/apps/details?id=com.lwcx.lw032 I found GPS strength bits from the packet 588b. here is example of my pcap. 588b0efefffdff0800fe80200000cce406fe

588b0e header feff roll=-2 fdff pitch=-3 0800 yaw=8 fe80200000 ??? cc GPS Strength = 0b11001100 (bits 2-6) =19 e4 ?? 06 controller status fe checksum

image