-
Notifications
You must be signed in to change notification settings - Fork 110
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for adis1550 and adis16550w
Signed-off-by: rbudai <robert.budai@analog.com>
Showing
3 changed files
with
528 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,464 @@ | ||
# Copyright (C) 2019-2024 Analog Devices, Inc. | ||
# | ||
# SPDX short identifier: ADIBSD | ||
|
||
from abc import ABC, abstractmethod | ||
|
||
from adi.attribute import attribute | ||
from adi.context_manager import context_manager | ||
from adi.rx_tx import rx | ||
|
||
|
||
class adis16550(rx, context_manager, ABC): | ||
|
||
_complex_data = False | ||
|
||
_rx_channel_names = [ | ||
"anglvel_x", | ||
"anglvel_y", | ||
"anglvel_z", | ||
"accel_x", | ||
"accel_y", | ||
"accel_z", | ||
"temp0", | ||
] | ||
|
||
_device_name = "" | ||
|
||
"""Disable mapping of trigger to RX device.""" | ||
disable_trigger = False | ||
|
||
# @property | ||
@abstractmethod | ||
def compatible_parts(self): | ||
raise NotImplementedError | ||
|
||
def __init__(self, uri="", device_name=None, trigger_name=None): | ||
context_manager.__init__(self, uri, self._device_name) | ||
|
||
if not device_name: | ||
device_name = self.compatible_parts[0] | ||
|
||
if device_name not in self.compatible_parts: | ||
raise Exception( | ||
"Not a compatible device:" | ||
+ str(device_name) | ||
+ ".Please select from:" | ||
+ str(self.compatible_parts) | ||
) | ||
else: | ||
self._ctrl = self._ctx.find_device(device_name) | ||
self._rxadc = self._ctx.find_device(device_name) | ||
if not trigger_name: | ||
trigger_name = device_name + "-dev0" | ||
|
||
if self._ctrl is None: | ||
print( | ||
"No device found with device_name = " | ||
+ device_name | ||
+ ". Searching for a device found in the compatible list." | ||
) | ||
for i in self.compatible_parts: | ||
self._ctrl = self._ctx.find_device(i) | ||
self._rxadc = self._ctx.find_device(i) | ||
if self._ctrl is not None: | ||
print("Fond device = " + i + ". Will use this device instead.") | ||
break | ||
if self._ctrl is None: | ||
raise Exception("No compatible device found") | ||
|
||
self.anglvel_x = self._anglvel_accel_channels(self._ctrl, "anglvel_x") | ||
self.anglvel_y = self._anglvel_accel_channels(self._ctrl, "anglvel_y") | ||
self.anglvel_z = self._anglvel_accel_channels(self._ctrl, "anglvel_z") | ||
self.accel_x = self._anglvel_accel_channels(self._ctrl, "accel_x") | ||
self.accel_y = self._anglvel_accel_channels(self._ctrl, "accel_y") | ||
self.accel_z = self._anglvel_accel_channels(self._ctrl, "accel_z") | ||
self.temp = self._temp_channel(self._ctrl, "temp0") | ||
self.deltaangl_x = self._delta_channels(self._ctrl, "deltaangl_x") | ||
self.deltaangl_y = self._delta_channels(self._ctrl, "deltaangl_y") | ||
self.deltaangl_z = self._delta_channels(self._ctrl, "deltaangl_z") | ||
self.deltavelocity_x = self._delta_channels(self._ctrl, "deltavelocity_x") | ||
self.deltavelocity_y = self._delta_channels(self._ctrl, "deltavelocity_y") | ||
self.deltavelocity_z = self._delta_channels(self._ctrl, "deltavelocity_z") | ||
|
||
# Set default trigger | ||
if not self.disable_trigger: | ||
self._trigger = self._ctx.find_device(trigger_name) | ||
self._rxadc._set_trigger(self._trigger) | ||
|
||
rx.__init__(self) | ||
self.rx_buffer_size = 16 # Make default buffer smaller | ||
|
||
def __get_scaled_sensor(self, channel_name: str) -> float: | ||
raw = self._get_iio_attr(channel_name, "raw", False) | ||
scale = self._get_iio_attr(channel_name, "scale", False) | ||
|
||
return raw * scale | ||
|
||
def __get_scaled_sensor_temp(self, channel_name: str) -> float: | ||
raw = self._get_iio_attr(channel_name, "raw", False) | ||
scale = self._get_iio_attr(channel_name, "scale", False) | ||
offset = self._get_iio_attr(channel_name, "offset", False) | ||
|
||
return (raw + offset) * scale | ||
|
||
def get_anglvel_x(self): | ||
"""Value returned in radians per second.""" | ||
return self.__get_scaled_sensor("anglvel_x") | ||
|
||
anglvel_x_conv = property(get_anglvel_x, None) | ||
|
||
def get_anglvel_y(self): | ||
"""Value returned in radians per second.""" | ||
return self.__get_scaled_sensor("anglvel_y") | ||
|
||
anglvel_y_conv = property(get_anglvel_y, None) | ||
|
||
def get_anglvel_z(self): | ||
"""Value returned in radians per second.""" | ||
return self.__get_scaled_sensor("anglvel_z") | ||
|
||
anglvel_z_conv = property(get_anglvel_z, None) | ||
|
||
def get_accel_x(self): | ||
"""Value returned in meters per squared second.""" | ||
return self.__get_scaled_sensor("accel_x") | ||
|
||
accel_x_conv = property(get_accel_x, None) | ||
|
||
def get_accel_y(self): | ||
"""Value returned in meters per squared second.""" | ||
return self.__get_scaled_sensor("accel_y") | ||
|
||
accel_y_conv = property(get_accel_y, None) | ||
|
||
def get_accel_z(self): | ||
"""Value returned in meters per squared second.""" | ||
return self.__get_scaled_sensor("accel_z") | ||
|
||
accel_z_conv = property(get_accel_z, None) | ||
|
||
def get_temp(self): | ||
"""Value returned in millidegrees Celsius.""" | ||
return self.__get_scaled_sensor_temp("temp0") | ||
|
||
temp_conv = property(get_temp, None) | ||
|
||
def get_deltaangl_x(self): | ||
"""Value returned in radians.""" | ||
return self.__get_scaled_sensor("deltaangl_x") | ||
|
||
deltaangl_x_conv = property(get_deltaangl_x, None) | ||
|
||
def get_deltaangl_y(self): | ||
"""Value returned in radians.""" | ||
return self.__get_scaled_sensor("deltaangl_y") | ||
|
||
deltaangl_y_conv = property(get_deltaangl_y, None) | ||
|
||
def get_deltaangl_z(self): | ||
"""Value returned in radians.""" | ||
return self.__get_scaled_sensor("deltaangl_z") | ||
|
||
deltaangl_z_conv = property(get_deltaangl_z, None) | ||
|
||
def get_deltavelocity_x(self): | ||
"""Value returned in meters per second.""" | ||
return self.__get_scaled_sensor("deltavelocity_x") | ||
|
||
deltavelocity_x_conv = property(get_deltavelocity_x, None) | ||
|
||
def get_deltavelocity_y(self): | ||
"""Value returned in meters per second.""" | ||
return self.__get_scaled_sensor("deltavelocity_y") | ||
|
||
deltavelocity_y_conv = property(get_deltavelocity_y, None) | ||
|
||
def get_deltavelocity_z(self): | ||
"""Value returned in meters per second.""" | ||
return self.__get_scaled_sensor("deltavelocity_z") | ||
|
||
deltavelocity_z_conv = property(get_deltavelocity_z, None) | ||
|
||
@property | ||
def sample_rate(self): | ||
"""sample_rate: Sample rate in samples per second""" | ||
return self._get_iio_dev_attr("sampling_frequency") | ||
|
||
@sample_rate.setter | ||
def sample_rate(self, value): | ||
self._set_iio_dev_attr_str("sampling_frequency", value) | ||
|
||
@property | ||
def current_timestamp_clock(self): | ||
"""current_timestamp_clock: Source clock for timestamps""" | ||
return self._get_iio_dev_attr("current_timestamp_clock") | ||
|
||
@current_timestamp_clock.setter | ||
def current_timestamp_clock(self, value): | ||
self._set_iio_dev_attr_str("current_timestamp_clock", value) | ||
|
||
@property | ||
def anglvel_x_calibbias(self): | ||
"""User calibration offset for gyroscope for the x-axis.""" | ||
return self._get_iio_attr("anglvel_x", "calibbias", False) | ||
|
||
@anglvel_x_calibbias.setter | ||
def anglvel_x_calibbias(self, value): | ||
self._set_iio_attr("anglvel_x", "calibbias", False, value) | ||
|
||
@property | ||
def anglvel_y_calibbias(self): | ||
"""User calibration offset for gyroscope for the y-axis.""" | ||
return self._get_iio_attr("anglvel_y", "calibbias", False) | ||
|
||
@anglvel_y_calibbias.setter | ||
def anglvel_y_calibbias(self, value): | ||
self._set_iio_attr("anglvel_y", "calibbias", False, value) | ||
|
||
@property | ||
def anglvel_z_calibbias(self): | ||
"""User calibration offset for gyroscope for the z-axis.""" | ||
return self._get_iio_attr("anglvel_z", "calibbias", False) | ||
|
||
@anglvel_z_calibbias.setter | ||
def anglvel_z_calibbias(self, value): | ||
self._set_iio_attr("anglvel_z", "calibbias", False, value) | ||
|
||
@property | ||
def accel_x_calibbias(self): | ||
"""User calibration offset for accelerometer for the x-axis.""" | ||
return self._get_iio_attr("accel_x", "calibbias", False) | ||
|
||
@accel_x_calibbias.setter | ||
def accel_x_calibbias(self, value): | ||
self._set_iio_attr("accel_x", "calibbias", False, value) | ||
|
||
@property | ||
def accel_y_calibbias(self): | ||
"""User calibration offset for accelerometer for the y-axis.""" | ||
return self._get_iio_attr("accel_y", "calibbias", False) | ||
|
||
@accel_y_calibbias.setter | ||
def accel_y_calibbias(self, value): | ||
self._set_iio_attr("accel_y", "calibbias", False, value) | ||
|
||
@property | ||
def accel_z_calibbias(self): | ||
"""User calibration offset for accelerometer for the z-axis.""" | ||
return self._get_iio_attr("accel_z", "calibbias", False) | ||
|
||
@accel_z_calibbias.setter | ||
def accel_z_calibbias(self, value): | ||
self._set_iio_attr("accel_z", "calibbias", False, value) | ||
|
||
@property | ||
def anglvel_x_calibscale(self): | ||
"""Calibscale value for gyroscope for the x-axis.""" | ||
return self._get_iio_attr("anglvel_x", "calibscale", False) | ||
|
||
@anglvel_x_calibscale.setter | ||
def anglvel_x_calibscale(self, value): | ||
self._set_iio_attr("anglvel_x", "calibscale", False, value) | ||
|
||
@property | ||
def anglvel_y_calibscale(self): | ||
"""Calibscale value for gyroscope for the y-axis.""" | ||
return self._get_iio_attr("anglvel_y", "calibscale", False) | ||
|
||
@anglvel_y_calibscale.setter | ||
def anglvel_y_calibscale(self, value): | ||
self._set_iio_attr("anglvel_y", "calibscale", False, value) | ||
|
||
@property | ||
def anglvel_z_calibscale(self): | ||
"""Calibscale value for gyroscope for the z-axis.""" | ||
return self._get_iio_attr("anglvel_z", "calibscale", False) | ||
|
||
@anglvel_z_calibscale.setter | ||
def anglvel_z_calibscale(self, value): | ||
self._set_iio_attr("anglvel_z", "calibscale", False, value) | ||
|
||
@property | ||
def accel_x_calibscale(self): | ||
"""Calibscale value for accelerometer for the x-axis.""" | ||
return self._get_iio_attr("accel_x", "calibscale", False) | ||
|
||
@accel_x_calibscale.setter | ||
def accel_x_calibscale(self, value): | ||
self._set_iio_attr("accel_x", "calibscale", False, value) | ||
|
||
@property | ||
def accel_y_calibscale(self): | ||
"""Calibcale value for accelerometer for the y-axis.""" | ||
return self._get_iio_attr("accel_y", "calibscale", False) | ||
|
||
@accel_y_calibscale.setter | ||
def accel_y_calibscale(self, value): | ||
self._set_iio_attr("accel_y", "calibscale", False, value) | ||
|
||
@property | ||
def accel_z_calibscale(self): | ||
"""Calibscale for accelerometer for the z-axis.""" | ||
return self._get_iio_attr("accel_z", "calibscale", False) | ||
|
||
@accel_z_calibscale.setter | ||
def accel_z_calibscale(self, value): | ||
self._set_iio_attr("accel_z", "calibscale", False, value) | ||
|
||
@property | ||
def anglvel_x_filter_low_pass_3db_frequency(self): | ||
"""Bandwidth for gyroscope for the x-axis.""" | ||
return self._get_iio_attr("anglvel_x", "filter_low_pass_3db_frequency", False) | ||
|
||
@anglvel_x_filter_low_pass_3db_frequency.setter | ||
def anglvel_x_filter_low_pass_3db_frequency(self, value): | ||
self._set_iio_attr("anglvel_x", "filter_low_pass_3db_frequency", False, value) | ||
|
||
@property | ||
def anglvel_y_filter_low_pass_3db_frequency(self): | ||
"""Bandwidth for gyroscope for the y-axis.""" | ||
return self._get_iio_attr("anglvel_y", "filter_low_pass_3db_frequency", False) | ||
|
||
@anglvel_y_filter_low_pass_3db_frequency.setter | ||
def anglvel_y_filter_low_pass_3db_frequency(self, value): | ||
self._set_iio_attr("anglvel_y", "filter_low_pass_3db_frequency", False, value) | ||
|
||
@property | ||
def anglvel_z_filter_low_pass_3db_frequency(self): | ||
"""Bandwidth for gyroscope for the z-axis.""" | ||
return self._get_iio_attr("anglvel_z", "filter_low_pass_3db_frequency", False) | ||
|
||
@anglvel_z_filter_low_pass_3db_frequency.setter | ||
def anglvel_z_filter_low_pass_3db_frequency(self, value): | ||
self._set_iio_attr("anglvel_z", "filter_low_pass_3db_frequency", False, value) | ||
|
||
@property | ||
def accel_x_filter_low_pass_3db_frequency(self): | ||
"""Bandwidth for accelerometer for the x-axis.""" | ||
return self._get_iio_attr("accel_x", "filter_low_pass_3db_frequency", False) | ||
|
||
@accel_x_filter_low_pass_3db_frequency.setter | ||
def accel_x_filter_low_pass_3db_frequency(self, value): | ||
self._set_iio_attr("accel_x", "filter_low_pass_3db_frequency", False, value) | ||
|
||
@property | ||
def accel_y_filter_low_pass_3db_frequency(self): | ||
"""Bandwidth for accelerometer for the y-axis.""" | ||
return self._get_iio_attr("accel_y", "filter_low_pass_3db_frequency", False) | ||
|
||
@accel_y_filter_low_pass_3db_frequency.setter | ||
def accel_y_filter_low_pass_3db_frequency(self, value): | ||
self._set_iio_attr("accel_y", "filter_low_pass_3db_frequency", False, value) | ||
|
||
@property | ||
def accel_z_filter_low_pass_3db_frequency(self): | ||
"""Bandwidth for accelerometer for the z-axis.""" | ||
return self._get_iio_attr("accel_z", "filter_low_pass_3db_frequency", False) | ||
|
||
@accel_z_filter_low_pass_3db_frequency.setter | ||
def accel_z_filter_low_pass_3db_frequency(self, value): | ||
self._set_iio_attr("accel_z", "filter_low_pass_3db_frequency", False, value) | ||
|
||
class _temp_channel(attribute): | ||
"""ADIS16550 temperature channel.""" | ||
|
||
def __init__(self, ctrl, channel_name): | ||
self.name = channel_name | ||
self._ctrl = ctrl | ||
|
||
@property | ||
def raw(self): | ||
"""ADIS16550 raw value""" | ||
return self._get_iio_attr(self.name, "raw", False) | ||
|
||
@property | ||
def scale(self): | ||
"""ADIS16550 scale value""" | ||
return self._get_iio_attr(self.name, "scale", False) | ||
|
||
@property | ||
def offset(self): | ||
"""ADIS16550 offset value""" | ||
return self._get_iio_attr(self.name, "offset", False) | ||
|
||
class _simple_channel(attribute): | ||
"""ADIS16550 basic channel, only scale an raw values""" | ||
|
||
def __init__(self, ctrl, channel_name): | ||
self.name = channel_name | ||
self._ctrl = ctrl | ||
|
||
@property | ||
def raw(self): | ||
"""ADIS16550 raw value""" | ||
return self._get_iio_attr(self.name, "raw", False) | ||
|
||
@property | ||
def scale(self): | ||
"""ADIS16550 scale value""" | ||
return self._get_iio_attr(self.name, "scale", False) | ||
|
||
class _extended_channel(_simple_channel): | ||
"""ADIS16550 pressure channel.""" | ||
|
||
def __init__(self, ctrl, channel_name): | ||
self.name = channel_name | ||
self._ctrl = ctrl | ||
|
||
@property | ||
def calibbias(self): | ||
"""ADIS16550 calibration offset""" | ||
return self._get_iio_attr(self.name, "calibbias", False) | ||
|
||
@calibbias.setter | ||
def calibbias(self, value): | ||
self._set_iio_attr(self.name, "calibbias", False, value) | ||
|
||
@property | ||
def calibscale(self): | ||
"""ADIS16550 calibration scale""" | ||
return self._get_iio_attr(self.name, "calibscale", False) | ||
|
||
@calibscale.setter | ||
def calibscale(self, value): | ||
self._set_iio_attr(self.name, "calibscale", False, value) | ||
|
||
@property | ||
def filter_low_pass_3db_frequency(self): | ||
"""ADIS16550 channel bandwidth""" | ||
return self._get_iio_attr(self.name, "filter_low_pass_3db_frequency", False) | ||
|
||
@filter_low_pass_3db_frequency.setter | ||
def filter_low_pass_3db_frequency(self, value): | ||
self._set_iio_attr(self.name, "filter_low_pass_3db_frequency", False, value) | ||
|
||
class _anglvel_accel_channels(_extended_channel): | ||
"""ADIS16550 gyro and accelerometer channels.""" | ||
|
||
def __init__(self, ctrl, channel_name): | ||
self.name = channel_name | ||
self._ctrl = ctrl | ||
|
||
class _delta_channels(_simple_channel): | ||
"""ADIS16550 delta angle and delta velocity channels.""" | ||
|
||
def __init__(self, ctrl, channel_name): | ||
self.name = channel_name | ||
self._ctrl = ctrl | ||
|
||
|
||
class adis16550(adis16550): | ||
"""ADIS1655X Six Degrees of Freedom Inertial Sensor | ||
This class is compatible with the following parts: | ||
- ADIS16550 | ||
- ADIS16550W | ||
Args: | ||
uri: URI of IIO context with ADIS16550 device | ||
device_name: Name of the device in the IIO context. Default is adis16550 | ||
trigger_name: Name of the trigger in the IIO context. Default is adis16550-dev0 | ||
""" | ||
|
||
compatible_parts = ["adis16550", "adis16550w"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Copyright (C) 2024 Analog Devices, Inc. | ||
# | ||
# SPDX short identifier: ADIBSD | ||
import sys | ||
|
||
import adi | ||
import matplotlib.pyplot as plt | ||
|
||
# Set up ADIS16550 | ||
my_dev_name = sys.argv[1] | ||
my_uri = sys.argv[2] | ||
|
||
dev = adi.adis16550(device_name=my_dev_name, uri=my_uri) | ||
|
||
dev.rx_output_type = "raw" | ||
dev.rx_enabled_channels = [0, 1, 2, 3, 4, 5] | ||
dev.sample_rate = 10 | ||
dev.rx_buffer_size = 10 | ||
|
||
print("Product id: " + str(dev.product_id)) | ||
print("Serial number: " + dev.serial_number) | ||
print("Firmware revision: " + dev.firmware_revision) | ||
print("Firmware date: " + dev.firmware_date) | ||
|
||
print("\nX acceleration: " + str(dev.accel_x_conv) + " m/s^2") | ||
print("Y acceleration: " + str(dev.accel_y_conv) + " m/s^2") | ||
print("Z acceleration: " + str(dev.accel_z_conv) + " m/s^2") | ||
|
||
print("\nX angular velocity: " + str(dev.anglvel_x_conv) + " rad/s") | ||
print("Y angular velocity: " + str(dev.anglvel_y_conv) + " rad/s") | ||
print("Z angular velocity: " + str(dev.anglvel_z_conv) + " rad/s") | ||
|
||
print("\nX delta velocity: " + str(dev.deltavelocity_x_conv) + " m/s") | ||
print("Y delta velocity: " + str(dev.deltavelocity_y_conv) + " m/s") | ||
print("Z delta velocity: " + str(dev.deltavelocity_z_conv) + " m/s") | ||
|
||
print("\nX delta angle: " + str(dev.deltaangl_x_conv) + " rad") | ||
print("Y delta angle: " + str(dev.deltaangl_y_conv) + " rad") | ||
print("Z delta angle: " + str(dev.deltaangl_z_conv) + " rad") | ||
|
||
dev.sample_rate = 2000 | ||
dev.magn_x_filter_low_pass_3db_frequency = 100 | ||
dev.anglvel_y_calibscale = 30 | ||
dev.anglvel_x_calibbias = 100 | ||
|
||
print("\nSampling frequency: " + str(dev.sample_rate)) | ||
|
||
print("Temperature raw value: " + str(dev.temp.raw)) | ||
print("Temperature scale value: " + str(dev.temp.scale)) | ||
print("Temperature offset value: " + str(dev.temp.offset)) | ||
|
||
print("X-axis gyro channel calibbias value: " + str(dev.anglvel_x_calibbias)) | ||
print("X-axis gyro channel calibscale value: " + str(dev.anglvel_y_calibscale)) | ||
print("X-axis magnetometer bandwidth: " + str(dev.magn_x_filter_low_pass_3db_frequency)) | ||
|
||
for _ in range(100): | ||
data = dev.rx() | ||
plt.clf() | ||
for i, d in enumerate(data): | ||
plt.plot(d, label=dev._rx_channel_names[dev.rx_enabled_channels[i]]) | ||
plt.legend() | ||
plt.show(block=False) | ||
plt.pause(0.1) |