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

Only getting data in "Orientation Quaternion" mode, no other modes #11

Open
aero-man opened this issue Oct 7, 2020 · 9 comments
Open

Comments

@aero-man
Copy link

aero-man commented Oct 7, 2020

Hello,

I have a Python script that is successfully getting data from a single sensor. However, no matter which setting I write to the Control Characteristic, I appear to only be getting data in "Orientation Quaternion" mode. No matter which mode I specify at the end of my byte string (for example, b'\x01\x01\x02' for "Extended (Quaternion)" mode), the data I get in the notifications is not 36 bytes as expected, but only 20 bytes. After converting the 20 bytes that I do get to numbers, it looks like I get a timestamp (uint32) and 4 chunks of quaternion data (each a 32-bit float for quaternion W, X, Y, and Z). When I write my enable message b'\x01\x01\x02' to the Control Characteristic, I also read it back to ensure that it was written properly, and it does read b'\x01\x01\x02' like I expect.

Another source of confusion is that when I get a notification with some sensor data, the notification says it was sent from handle 39 (the handle for the medium payload length characteristic), and yet the data I am getting is supposed to be sent from the short payload length characteristic, which should have a handle of 43.

Is there another step to enabling these sensors and setting the measurement mode that I am missing? My current understanding is outlined in Issue #7 and is copied below:

  1. Scan for the sensor (can skip this if you already know the Bluetooth address)
  2. Connect to the sensor using the Bluetooth address found via scanning
  3. Subscribe to the Measurement Characteristic by writing an enable message to that characteristic's CCCD, which is at integer handle + 1 (e.g. if the characteristic's handle is 39, write to its CCCD at handle 40) (There are two measurement characteristics to choose from for Xsens DOTs, depending on whether your measurement type is a short or medium payload)
  4. Write an enable message to the Control Characteristic
  5. Add a delegate to your sensor to start listening for notifications from the sensor
  6. Run a loop to listen for notifications and do something with the data received. (The example below just prints it.)

Thanks for your help.

@aero-man
Copy link
Author

aero-man commented Oct 7, 2020

This may actually be an issue with how I am processing the buffers my script receives. Will report back tomorrow if I still need assistance.

@aero-man
Copy link
Author

Update: confirmed that I am only getting 20-byte notifications, regardless of what my script does with that data.

@fancycww
Copy link
Contributor

@aero-man
Hi,
This project is using nodejs.
I'm not familiar with Python, but I think it's similar to write data to Bluetooth.
After successful writing, data notifications will be received.
Does Python divide the data into multiple pieces?
Thanks.

@freddijkstra
Copy link
Collaborator

When Python informs the application of each received notification packet, then it is to be expected that the data-size is 20-bytes as that is the size of the user data in a notification packet. It would be strange however since the stack should stitch the larger notifications together as one data-block.

@aero-man
Copy link
Author

aero-man commented Oct 13, 2020

Thanks @fancycww and @freddijkstra for the tips. I will investigate again how Python and Bluepy are breaking up the data.

@aero-man
Copy link
Author

Here are ten lines of sensor data that I am getting from a single sensor. Though I set the sensor to "Extended (Quaternion)" mode, which should be 40 bytes, I am only getting 20 bytes. It does not appear that the script is dividing the DOT notification into two separate 20-byte notifications, since each line has a legitimate timestamp in the expected order. If every other line was actually the second 20-byte chunk of the overall notification, I'd expect the timestamp to be some accelerometer or gyro value that got accidentally interpreted as a timestamp and thus be something very different from 29873xxxxx and so on.

[(2987388214, 0.6987149, 0.00213826, 0.00411566, -0.7153855)]
[(2987404881, 0.6987097, 0.00213495, 0.00412598, -0.71539044)]
[(2987421548, 0.69870615, 0.00214881, 0.00411967, -0.71539396)]
[(2987438215, 0.6987045, 0.00214634, 0.00412696, -0.7153956)]
[(2987454882, 0.6987034, 0.00213842, 0.00412312, -0.71539664)]
[(2987471549, 0.6987081, 0.00214344, 0.00411941, -0.715392)]
[(2987488216, 0.6987105, 0.00214916, 0.00412804, -0.7153896)]
[(2987504883, 0.6987047, 0.00214807, 0.00411882, -0.7153953)]
[(2987521550, 0.69870716, 0.00215218, 0.00411918, -0.7153929)]
[(2987538217, 0.69870716, 0.00215312, 0.00412477, -0.7153929)]

Thanks again.

@FrederikPetri
Copy link

@aero-man
Hi,
Very useful python script #7 , thanks for sharing! Can you explain how you convert the raw sensor data you print in the example code to timestamp and quaternions?

@aero-man
Copy link
Author

aero-man commented Nov 20, 2020

I'm still trying to debug this issue. Still only getting 20 bytes of data. Looking at the underlying code in Bluepy.

Do you guys know what the Bluetooth packet looks like when it leaves the sensor. Is there any documentation available on this? I'm having Bluepy print out what it gets from the sensors, and each packet looks like this:
rsp=$ntfy\x1ehnd=h27\x1ed=b4479A0E3A1FDA53C3DA7633FACF2E9BE7723DCBA\n
Is this what it is supposed to look like? Trying to rule out whether this is a problem with how Bluepy is parsing the data.

Thanks.

@aero-man
Copy link
Author

@FrederikPetri I am using Numpy.

import numpy as np
...
data_type = np.dtype([('timestamp', np.uint32), ('quat_w', np.float32), ('quat_x', np.float32),
                       ('quat_y', np.float32), ('quat_z', np.float32)])
human_readable_data = np.frombuffer(data, dtype=data_type)

This code lives in the callback function handleNotification(cHandle, data) that's part of Bluepy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants