In this example, the sensor data is read from the pozyx shield (either the shield mounted on the Arduino, or a remote shield). To visualize all the data, we use Processing. Below a screenshot of the Processing program showing all the sensor data graphically.
This example requires one or two pozyx shields. If all tools are installed, open up orientation_3D.py in the Pozyx library’s tutorial folder. Probably, the path to this file will be "Downloads/Pozyx-Python-library/tutorials/orientation_3D.py". You can run the script from either command line or a text editor that allows running the scripts as well. If you're on Windows and have installed Python, you might be able to simply double-click it. If you you get an error, you likely forgot to install pythonosc, you can do this easily using
pip install python-osc.
Open up the pozyx_orientation3D.pde sketch in Processing, as this example will be directly visualized.
In Processing, make sure serial is set to
false. Unless you need port 8888 for something else, you can leave both the Python script and Processing sketch intact. The data will automatically be sent using OSC on port 8888.
You should be able to physically rotate your Pozyx now and directly see it rotate in Processing as well. There are plots on the side and at the top, but what do they all mean?
We'll now go over the code that's needed to retrieve all sensor data. Looking at the code's parameters, we can see that we can once again use a remote Pozyx for this. This means that you could for example attach a Pozyx to a ball, and watch the ball's spin directly on your screen as well with the Pozyx.
Imports and setup
We import the pypozyx library and the IMU interrupt flag from its bitmasks, and pythonosc so that we can send the sensor data to Processing over OSC. The addition of the default time library import allows us to measure the time between different measurements.
We initialize the PozyxSerial and UDP socket over which we'll send the data, and the setup then sets the last measured time right.
from time import time from pypozyx import * from pypozyx.definitions.bitmasks import POZYX_INT_MASK_IMU from pythonosc.osc_message_builder import OscMessageBuilder from pythonosc.udp_client import SimpleUDPClient
def setup(self): """There is no specific setup functionality""" self.current_time = time()
The main loop deserves to be elaborated on. The Pozyx's IMU sensors trigger an interrupt flag when there is new data available, and in the code we wait for this flag to trigger explicitly.
When checkForFlag returns POZYX_SUCCESS, meaning that POZYX_INT_MASK_IMU was raised and new IMU data is available, or when we're retrieving sensor data remotely, all sensor data and the calibration status will be read from the (remote) Pozyx and packed in a OSC message, which is then interpreted by the Processing sketch. You can see that there is a SensorData object available for this, which automatically converts the sensor data to its respective standard units.
def loop(self): """Gets new IMU sensor data""" sensor_data = SensorData() calibration_status = SingleRegister() if self.remote_id is not None or self.pozyx.checkForFlag(POZYX_INT_MASK_IMU, 0.01) == POZYX_SUCCESS: status = self.pozyx.getAllSensorData(sensor_data, self.remote_id) status &= self.pozyx.getCalibrationStatus(calibration_status, self.remote_id) if status == POZYX_SUCCESS: self.publishSensorData(sensor_data, calibration_status)
The calibration status gives information about the quality of the sensor orientation data. When the system is not fully calibrated, the orientation estimation can be bad. The calibration status is a 8-bit variable where every 2 bits represent a different piece of calibration info.
You're at the end of the standard tutorials that introduce you to all of Pozyx's basic functionality: ranging, positioning, and its IMU. If you haven't already done so and have the number of devices necessary, you can read the multitag tutorial. When you start work on your own prototype, don't be afraid to delve into our documentation which should suffice for all your needs.