acconeer / acconeer-python-exploration

Acconeer Exploration Tool

Home Page:https://docs.acconeer.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Com port issue with exploration tool Xm112/Xb112

nehabhootesh opened this issue · comments

commented

Hello team, we have started working with xm112 and xb112 for our mini project. We followed all steps as in the youtube channel (acconeer official yt channel), but after starting exploration tool on windows 10 ad ubantu we are facing the issue with the com port. we checked with the device manager and port is clearly mentioned as com3. Ubantu we used command prompt and it showed as usb0. But lately both the exploration tools are not connecting to the server.
Here is the screenshot of both windows and ubantu
Screenshot from 2023-04-05 12-19-36
Screenshot 2023-04-05 121555
we have used the latest exploration tool software available in the official website.
Versions used:
windows 10
python 3.10.6
exploration tool: latest using command prompt
Bossa version: bossa-x64-1.9.1.msi
Module SW for XM112: 2.14.2

We are waiting for someone to help us out earliest!!
Thanks and regards
Neha B

commented

Hey can someone look into our issue and resolve it earliest!
Thanks
Neha B

commented

python3 -m acconeer.exptool.app
qt.dbus.integration: Could not connect "org.freedesktop.IBus" to globalEngineChanged(QString)
16:05:24.778 | INFO | MainProcess | acconeer.exptool.app.old.app | Loaded configuration from last session: /home/sitec/.local/share/acconeer_exptool/last_config.npy
16:05:33.146 | WARNING | MainProcess | acconeer.exptool.app.old.app | Overriding baudrate (115200)!
16:05:33.248 | INFO | MainProcess | acconeer.exptool.a111._clients.base | reported version: 2.14.2
/usr/lib/python3/dist-packages/apport/report.py:13: DeprecationWarning: the imp module is deprecated in favour of importlib and slated for removal in Python 3.12; see the module's documentation for alternative uses
import fnmatch, glob, traceback, errno, sys, atexit, locale, imp, stat
Traceback (most recent call last):
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1169, in update_canvas
new_canvas = self.init_graphs()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 298, in init_graphs
self.reload_pg_updater(canvas=canvas)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 322, in reload_pg_updater
self.service_widget.setup(canvas.ci)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/a111/algo/envelope/ui.py", line 27, in setup
self.ampl_plot = win.addPlot(row=0, colspan=num_sensors)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsLayout.py", line 72, in addPlot
plot = PlotItem(**kargs)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/PlotItem/PlotItem.py", line 154, in init
self.titleLabel = LabelItem('', size='11pt', parent=self)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/LabelItem.py", line 19, in init
GraphicsWidget.init(self, parent)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsWidget.py", line 18, in init
QtWidgets.QGraphicsWidget.init(self, *args, **kwargs)
TypeError: GraphicsWidgetAnchor.init() takes 1 positional argument but 2 were given
Traceback (most recent call last):
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 664, in start_btn_clicked
self.start_scan()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1303, in start_scan
self.update_canvas(force_update=True)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1169, in update_canvas
new_canvas = self.init_graphs()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 298, in init_graphs
self.reload_pg_updater(canvas=canvas)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 322, in reload_pg_updater
self.service_widget.setup(canvas.ci)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/a111/algo/envelope/ui.py", line 27, in setup
self.ampl_plot = win.addPlot(row=0, colspan=num_sensors)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsLayout.py", line 72, in addPlot
plot = PlotItem(**kargs)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/PlotItem/PlotItem.py", line 154, in init
self.titleLabel = LabelItem('', size='11pt', parent=self)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/LabelItem.py", line 19, in init
GraphicsWidget.init(self, parent)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsWidget.py", line 18, in init
QtWidgets.QGraphicsWidget.init(self, *args, **kwargs)
TypeError: GraphicsWidgetAnchor.init() takes 1 positional argument but 2 were given
Traceback (most recent call last):
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 664, in start_btn_clicked
self.start_scan()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1303, in start_scan
self.update_canvas(force_update=True)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1169, in update_canvas
new_canvas = self.init_graphs()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 298, in init_graphs
self.reload_pg_updater(canvas=canvas)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 322, in reload_pg_updater
self.service_widget.setup(canvas.ci)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/a111/algo/envelope/ui.py", line 27, in setup
self.ampl_plot = win.addPlot(row=0, colspan=num_sensors)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsLayout.py", line 72, in addPlot
plot = PlotItem(**kargs)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/PlotItem/PlotItem.py", line 154, in init
self.titleLabel = LabelItem('', size='11pt', parent=self)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/LabelItem.py", line 19, in init
GraphicsWidget.init(self, parent)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsWidget.py", line 18, in init
QtWidgets.QGraphicsWidget.init(self, *args, **kwargs)
TypeError: GraphicsWidgetAnchor.init() takes 1 positional argument but 2 were given
Traceback (most recent call last):
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 664, in start_btn_clicked
self.start_scan()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1303, in start_scan
self.update_canvas(force_update=True)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1169, in update_canvas
new_canvas = self.init_graphs()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 298, in init_graphs
self.reload_pg_updater(canvas=canvas)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 322, in reload_pg_updater
self.service_widget.setup(canvas.ci)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/a111/algo/envelope/ui.py", line 27, in setup
self.ampl_plot = win.addPlot(row=0, colspan=num_sensors)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsLayout.py", line 72, in addPlot
plot = PlotItem(**kargs)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/PlotItem/PlotItem.py", line 154, in init
self.titleLabel = LabelItem('', size='11pt', parent=self)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/LabelItem.py", line 19, in init
GraphicsWidget.init(self, parent)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsWidget.py", line 18, in init
QtWidgets.QGraphicsWidget.init(self, *args, **kwargs)
TypeError: GraphicsWidgetAnchor.init() takes 1 positional argument but 2 were given
Traceback (most recent call last):
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 664, in start_btn_clicked
self.start_scan()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1303, in start_scan
self.update_canvas(force_update=True)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 1169, in update_canvas
new_canvas = self.init_graphs()
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 298, in init_graphs
self.reload_pg_updater(canvas=canvas)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/app/old/app.py", line 322, in reload_pg_updater
self.service_widget.setup(canvas.ci)
File "/home/sitec/.local/lib/python3.10/site-packages/acconeer/exptool/a111/algo/envelope/ui.py", line 27, in setup
self.ampl_plot = win.addPlot(row=0, colspan=num_sensors)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsLayout.py", line 72, in addPlot
plot = PlotItem(**kargs)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/PlotItem/PlotItem.py", line 154, in init
self.titleLabel = LabelItem('', size='11pt', parent=self)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/LabelItem.py", line 19, in init
GraphicsWidget.init(self, parent)
File "/home/sitec/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/GraphicsWidget.py", line 18, in init
QtWidgets.QGraphicsWidget.init(self, *args, **kwargs)
TypeError: GraphicsWidgetAnchor.init() takes 1 positional argument but 2 were given
^C16:06:30.341 | INFO | MainProcess | acconeer.exptool.app.old.app | Saved configuration from this session to /home/sitec/.local/share/acconeer_exptool/last_config.npy
16:06:30.364 | INFO | MainProcess | acconeer.exptool.app.old.app | Saved configuration from this session to /home/sitec/.local/share/acconeer_exptool/last_config.npy
image
image

Hi,
Always make sure that the exploration tool is updated by following instructions for your OS.
When your saying "ubantu" I assume you mean Ubuntu?
From the Windows screenshot it looks like it is connecting without issues, but when it comes to Ubuntu it does not.

Is your Ubuntu running in a virtual box inside Windows?

For you second problem:
I have not been able to reproduce this. Can you make sure that the version you are using is v6.0.4?

Also, can you provide the output from 'pip list'?

BR
Anders

commented

Hey we were able to fix the com port issue but now we are facing problem while using IQ services. Frames are showing as missed in IQ service measurement but frames are not missed while using power bin services. We need IQ services for measuring the chest displacement for our project.
Here I have attached both the images of frames

57247005-d3bc-4a96-a0a4-17055f5cf22a

Uploading e504a525-6bcf-450d-86cc-6d792f4c7b66.jpg…

Hi,

The Power Bins service requires a lot less data than the IQ service and can achieve higher update rate. To reduce the number of missed frames you need to lower the update rate.

Are you running this on native Ubuntu or on Windows through a virtual machine?

commented

we are running on native ubuntu

commented

Where can I lower the update rate. May I know the settings please

Okay, good!

There is a setting in the GUI named 'update rate'. Try lowering that

commented

And we tried saving the data into .h5 file but we couldn't see any data saved into it.

commented

hey, we reduced the update rate still the frames are missed in IQ services.

what is your exact configuration? can you send a screenshot of the settings?

commented

Hey, I wanna know can we directly calculate breathe rate and heart rate on breakout board itself, like by performing digital signal processing algorithm written in python language and send the heart rate and breathing rate into the ai model(rzv2ma board) using usb? If yes, let me know the steps to get started !!. If not then how to get the breath rate and heart rate like do we need to stream the raw data to any processing unit for processing?? please reply soon.. we need to finish the project in 10 days, we have just started..
Thanks

Hi,

The breathing algorithm is only present in Python and available via Exploration Tool. Also, we have no support for the RZ/V2MA.

commented

Hey, may I know where can I get the code for sleep breathing, because I need to add heart rate calculation algorithm for the same file.

commented

hey I'm trying to run the python file on command prompt by merging all files, my aim is to jut print the breath rate on the command prompt but have been getting this error.
if data["init_progress"] is not None:
IndexError: only integers, slices (:), ellipsis (...), numpy.newaxis (None) and integer or boolean arrays are valid indices
Disconnecting...

Here is the complete code :
import numpy as np
import pg_processor_spoof
from scipy import signal
import acconeer.exptool as et

def main():
args = et.a111.ExampleArgumentParser().parse_args()
et.utils.config_logging(args)

client = et.a111.Client(**et.a111.get_client_args(args))

client.squeeze = False

sensor_config = et.a111.IQServiceConfig()
sensor_config.sensor = args.sensors
sensor_config.range_interval = [0.2, 1.0]
sensor_config.profile = sensor_config.Profile.PROFILE_2
sensor_config.hw_accelerated_average_samples = 20
sensor_config.downsampling_factor = 2
sensor_config.update_rate=60
sensor_config.gain=0.6

session_info = client.setup_session(sensor_config)
interrupt_handler = et.utils.ExampleInterruptHandler()
print("Press Ctrl-C to end session")
pg_updater = PGUpdater(sensor_config, None, session_info)
pg_process = pg_processor_spoof.PGProcess(pg_updater)
pg_process.start()
client.start_session()
while not interrupt_handler.got_signal:
    data_info, data = client.get_next()

    try:
        pg_process.put_data(data)
    except pg_processor_spoof.PGProccessDiedException:
        break

print("Disconnecting...")
pg_process.close()
client.disconnect()

class ProcessingConfiguration(et.configbase.ProcessingConfig):
VERSION = 1

n_dft = et.configbase.FloatParameter(
    label="Estimation window",
    unit="s",
    default_value=15,
    limits=(2, 20),
    updateable=False,
    order=0,
)

t_freq_est = et.configbase.FloatParameter(
    label="Time between estimation",
    unit="s",
    default_value=0.2,
    limits=(0.1, 10),
    updateable=False,
    order=10,
)

D = et.configbase.IntParameter(
    label="Distance downsampling",
    default_value=124,
    limits=(0, 248),
    updateable=False,
    order=20,
)

f_high = et.configbase.FloatParameter(
    label="Bandpass high freq",
    unit="Hz",
    default_value=0.8,
    limits=(0, 10),
    updateable=False,
    order=30,
)

f_low = et.configbase.FloatParameter(
    label="Bandpass low freq",
    unit="Hz",
    default_value=0.2,
    limits=(0, 10),
    updateable=False,
    order=40,
)

lambda_p = et.configbase.FloatParameter(
    label="Threshold: Peak to noise ratio",
    default_value=40,
    limits=(1, 1000),
    updateable=False,
    order=50,
)

lambda_05 = et.configbase.FloatParameter(
    label="Threshold: Peak to half harmonic ratio",
    default_value=1,
    limits=(0, 10),
    updateable=False,
    order=60,
)

class Processor:
def init(self, sensor_config, processing_config, session_info, calibration=None):
self.config = sensor_config

    # Settings
    # Data length for frequency estimation [s] | 20
    n_dft = processing_config.n_dft
    # Time between frequency estimations [s] | 2
    t_freq_est = processing_config.t_freq_est
    # Time constant low-pass filter on IQ-data [s] | 0.04
    tau_iq = 0.04
    # Time constant low-pass filter on IQ-data [s] | 150
    self.f_s = self.config.update_rate
    # Spatial or Range down sampling factor | 124
    self.D = processing_config.D
    # Lowest frequency of interest [Hz] | 0.1
    self.f_low = processing_config.f_low
    # Highest frequency of interest [Hz] | 1
    self.f_high = processing_config.f_high
    # Time down sampling for DFT | 40 f_s/M ~ 10 Hz
    self.M = int(self.f_s / 10)
    # Threshold: spectral peak to noise ratio [1] | 50
    self.lambda_p = processing_config.lambda_p
    # Threshold: ratio fundamental and half harmonic
    self.lambda_05 = processing_config.lambda_05
    # Interpolation between DFT points
    self.interpolate = True

    self.delta_f = 1 / n_dft
    self.dft_f_vec = np.arange(self.f_low, self.f_high, self.delta_f)
    self.dft_points = np.size(self.dft_f_vec)

    # Butterworth bandpass filter
    f_n = self.f_s / 2
    v_low = self.f_low / f_n
    v_high = self.f_high / f_n
    self.b, self.a = signal.butter(4, [v_low, v_high], btype="bandpass")

    # Exponential lowpass filter
    self.alpha_iq = np.exp(-2 / (self.f_s * tau_iq))
    self.alpha_phi = np.exp(-2 * self.f_low / self.f_s)

    # Parameter init
    self.sweeps_in_block = int(np.ceil(n_dft * self.f_s))
    self.new_sweeps_per_results = int(np.ceil(t_freq_est * self.f_s))
    self.phi_vec = np.zeros((self.sweeps_in_block, 1))
    self.f_est_vec = np.zeros(1)
    self.f_dft_est_vec = np.zeros(1)
    self.snr_vec = 0

    self.sweep_index = 0

def process(self, data, data_info):
    sweep = data

    if self.sweep_index == 0:
        delay_points = int(np.ceil(np.size(sweep) / self.D))
        self.data_s_d_mat = np.zeros((self.sweeps_in_block, delay_points), dtype="complex")
        self.data_s_d_mat[self.sweep_index, :] = self.downsample(sweep, self.D)

        out_data = None
    elif self.sweep_index < self.sweeps_in_block:
        self.data_s_d_mat[self.sweep_index, :] = self.iq_lp_filter_time(
            self.data_s_d_mat[self.sweep_index - 1, :], self.downsample(sweep, self.D)
        )

        temp_phi = self.unwrap_phase(
            self.phi_vec[self.sweep_index - 1],
            self.data_s_d_mat[self.sweep_index, :],
            self.data_s_d_mat[self.sweep_index - 1, :],
        )

        self.phi_vec[self.sweep_index] = self.unwrap_phase(
            self.phi_vec[self.sweep_index - 1],
            self.data_s_d_mat[self.sweep_index, :],
            self.data_s_d_mat[self.sweep_index - 1, :],
        )

        phi_filt = signal.lfilter(self.b, self.a, self.phi_vec, axis=0)

        out_data = {
            "phi_raw": self.phi_vec,
            "phi_filt": phi_filt,
            "power_spectrum": np.zeros(self.dft_points),
            "x_dft": np.linspace(self.f_low, self.f_high, self.dft_points),
            "f_dft_est_hist": self.f_dft_est_vec,
            "f_est_hist": self.f_est_vec,
            "f_dft_est": 0,
            "f_est": 0,
            "f_low": self.f_low,
            "f_high": self.f_high,
            "snr": 0,
            "lambda_p": self.lambda_p,
            "lambda_05": self.lambda_05,
            "dist_range": self.config.range_interval,
            "init_progress": round(100 * self.sweep_index / self.sweeps_in_block),
        }
    else:
        # Lowpass filter IQ data downsampled in distance points
        self.data_s_d_mat = np.roll(self.data_s_d_mat, -1, axis=0)
        self.data_s_d_mat[-1, :] = self.iq_lp_filter_time(
            self.data_s_d_mat[-2, :], self.downsample(sweep, self.D)
        )

        # Phase unwrapping of IQ data
        temp_phi = self.unwrap_phase(
            self.phi_vec[-1], self.data_s_d_mat[-1, :], self.data_s_d_mat[-2, :]
        )
        self.phi_vec = np.roll(self.phi_vec, -1, axis=0)
        self.phi_vec[-1] = temp_phi

        if np.mod(self.sweep_index, self.new_sweeps_per_results - 1) == 0:
            # Bandpass filter unwrapped data
            phi_filt_vec = signal.lfilter(self.b, self.a, self.phi_vec, axis=0)
            P, dft_est, _ = self.dft(self.downsample(phi_filt_vec, self.M))
            f_breath_est, _, snr, _ = self.breath_freq_est(P)

            self.f_est_vec = np.append(self.f_est_vec, f_breath_est)
            self.f_dft_est_vec = np.append(self.f_dft_est_vec, dft_est)
            self.snr_vec = np.append(self.snr_vec, snr)

            out_data = {
                "phi_raw": self.phi_vec,
                "phi_filt": phi_filt_vec,
                "power_spectrum": P,
                "x_dft": np.linspace(self.f_low, self.f_high, self.dft_points),
                "f_dft_est_hist": self.f_dft_est_vec,
                "f_est_hist": self.f_est_vec,
                "f_dft_est": dft_est,
                "f_est": f_breath_est,
                "f_low": self.f_low,
                "f_high": self.f_high,
                "snr": snr,
                "lambda_p": self.lambda_p,
                "lambda_05": self.lambda_05,
                "dist_range": self.config.range_interval,
                "init_progress": None,
            }
        else:
            out_data = None

    self.sweep_index += 1
    return out_data

def downsample(self, data, n):
    return data[::n]

def iq_lp_filter_time(self, state, new_data):
    return self.alpha_iq * state + (1 - self.alpha_iq) * new_data

def unwrap_phase(self, phase_lp, data_1, data_2):
    return phase_lp * self.alpha_phi + np.angle(np.mean(data_2 * np.conjugate(data_1)))

def dft(self, data):
    data = np.squeeze(data)
    n_vec = np.arange(data.size) * self.M
    dft = np.exp((2j * np.pi / self.f_s) * np.outer(self.dft_f_vec, n_vec))
    P = np.square(np.abs(np.matmul(dft, data)))
    idx_f = np.argmax(P)
    dft_est = self.dft_f_vec[idx_f]
    return P, dft_est, P[idx_f]

def noise_est(self, P):
    return np.mean(np.sort(P)[: (self.dft_points // 2) - 1])

def half_peak_frequency(self, P, f_est):
    idx_half = int(f_est / (2 * self.delta_f))
    if idx_half < self.f_low:
        return 0
    else:
        return (1 / self.delta_f) * (
            (self.dft_f_vec[idx_half + 1] - f_est / 2) * P[idx_half]
            + (f_est / 2 - self.dft_f_vec[idx_half]) * P[idx_half + 1]
        )

def breath_freq_est(self, P):
    f_idx = np.argmax(P)
    P_peak = P[f_idx]

    if self.interpolate:
        f_est, P_peak = self.freq_quad_interpolation(P)
    else:
        f_est = self.dft_f_vec[f_idx]

    P_half = self.half_peak_frequency(P, f_est)

    if P_peak < self.lambda_05 * P_half:
        f_est = f_est / 2
        P_peak = P_half

    if self.f_low < f_est < self.f_high and P_peak > self.lambda_p * self.noise_est(P):
        f_est_valid = True
    else:
        f_est_valid = False
        f_est = 0

    snr = P_peak / self.noise_est(P)
    print(f_est*60)
    return f_est, P_peak, snr, f_est_valid

def freq_quad_interpolation(self, P):
    f_idx = np.argmax(P)

    if 0 < f_idx < (P.size - 1) and P.size > 3:
        f_est = self.dft_f_vec[f_idx] + self.delta_f / 2 * (
            (np.log(P[f_idx + 1]) - np.log(P[f_idx - 1]))
            / (2 * np.log(P[f_idx]) - np.log(P[f_idx + 1]) - np.log(P[f_idx - 1]))
        )
        P_peak = P[f_idx] + np.exp(
            (1 / 8)
            * np.square(np.log(P[f_idx + 1]) - np.log(P[f_idx - 1]))
            / (2 * np.log(P[f_idx]) - np.log(P[f_idx + 1]) - np.log(P[f_idx - 1]))
        )

        if not (self.f_low < f_est < self.f_high):
            f_est = 0
    else:
        f_est = 0
        P_peak = 0

    return f_est, P_peak

class PGUpdater:
def init(self, sensor_config, processing_config, session_info):
self.config = sensor_config
def update(self, data):

    if data["init_progress"] is not None:
        self.spect_text_item.setText("Initiating: {} %".format(data["init_progress"]))
    else:
        snr = data["snr"]
        if snr == 0:
            s = "SNR: N/A | {:.0f} dB".format(10 * np.log10(data["lambda_p"]))
        else:
            fmt = "SNR: {:.0f} | {:.0f} dB"
            s = fmt.format(10 * np.log10(snr), 10 * np.log10(data["lambda_p"]))
        print(s)

        f_est = data["f_est"]
        if f_est > 0:
            s = "Latest frequency estimate: {:.2f} Hz | {:.0f} BPM".format(f_est, f_est * 60)
            print(s)

if name == "main":
main()

please help me!! I need to finish the project in 5 days
Thanks !!

commented

I copy pasted the same code available in algo but still getting the error
Press Ctrl-C to end session
Process Process-1:
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1776.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 314, in _bootstrap
self.run()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1776.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\nehab\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\acconeer\exptool\pg_process.py", line 65, in pg_process_program
updater.setup(win.ci)
File "C:\Users\nehab\Desktop\Trial\exacsamecopy.py", line 388, in setup
self.spect_smax = et.utils.SmoothMax(self.config.update_rate / 15)
TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
Disconnecting...

commented

Have been getting this error :
PS C:\Users\nehab\Desktop\Trial> python spoof.py -u COM3
Press Ctrl-C to end session
Traceback (most recent call last):
File "C:\Users\nehab\Desktop\Trial\spoof.py", line 330, in
out_data = proc(sensor_config, processing_config, session_info, calibration=None).process(data)
File "C:\Users\nehab\Desktop\Trial\spoof.py", line 102, in init
self.delta_f = 1.0 / n_dft
TypeError: unsupported operand type(s) for /: 'float' and 'FloatParameter'

the complete code:

import numpy as np
import pg_processor_spoof
from scipy import signal
import acconeer.exptool as et

class ProcessingConfiguration(et.configbase.ProcessingConfig):
VERSION = 1

n_dft = et.configbase.FloatParameter(
    label="Estimation window",
    unit="s",
    default_value=15,
    limits=(2, 20),
    updateable=False,
    order=0,
)

t_freq_est = et.configbase.FloatParameter(
    label="Time between estimation",
    unit="s",
    default_value=0.2,
    limits=(0.1, 10),
    updateable=False,
    order=10,
)

D = et.configbase.IntParameter(
    label="Distance downsampling",
    default_value=124,
    limits=(0, 248),
    updateable=False,
    order=20,
)

f_high = et.configbase.FloatParameter(
    label="Bandpass high freq",
    unit="Hz",
    default_value=0.8,
    limits=(0, 10),
    updateable=False,
    order=30,
)

f_low = et.configbase.FloatParameter(
    label="Bandpass low freq",
    unit="Hz",
    default_value=0.2,
    limits=(0, 10),
    updateable=False,
    order=40,
)

lambda_p = et.configbase.FloatParameter(
    label="Threshold: Peak to noise ratio",
    default_value=40,
    limits=(1, 1000),
    updateable=False,
    order=50,
)

lambda_05 = et.configbase.FloatParameter(
    label="Threshold: Peak to half harmonic ratio",
    default_value=1,
    limits=(0, 10),
    updateable=False,
    order=60,
)

processing_config=ProcessingConfiguration
class Processor:
def init(self, sensor_config, processing_config, session_info, calibration=None):
self.config = sensor_config

    # Settings
    # Data length for frequency estimation [s] | 20
    n_dft = processing_config.n_dft
    # Time between frequency estimations [s] | 2
    t_freq_est = processing_config.t_freq_est
    # Time constant low-pass filter on IQ-data [s] | 0.04
    tau_iq = 0.04
    # Time constant low-pass filter on IQ-data [s] | 150
    self.f_s = self.config.update_rate
    # Spatial or Range down sampling factor | 124
    self.D = processing_config.D
    # Lowest frequency of interest [Hz] | 0.1
    self.f_low = processing_config.f_low
    # Highest frequency of interest [Hz] | 1
    self.f_high = processing_config.f_high
    # Time down sampling for DFT | 40 f_s/M ~ 10 Hz
    self.M = int(self.f_s / 10)
    # Threshold: spectral peak to noise ratio [1] | 50
    self.lambda_p = processing_config.lambda_p
    # Threshold: ratio fundamental and half harmonic
    self.lambda_05 = processing_config.lambda_05
    # Interpolation between DFT points
    self.interpolate = True

    self.delta_f = 1.0 / n_dft
    self.dft_f_vec = np.arange(self.f_low, self.f_high, self.delta_f)
    self.dft_points = np.size(self.dft_f_vec)

    # Butterworth bandpass filter
    f_n = self.f_s / 2
    v_low = self.f_low / f_n
    v_high = self.f_high / f_n
    self.b, self.a = signal.butter(4, [v_low, v_high], btype="bandpass")

    # Exponential lowpass filter
    self.alpha_iq = np.exp(-2 / (self.f_s * tau_iq))
    self.alpha_phi = np.exp(-2 * self.f_low / self.f_s)

    # Parameter init
    self.sweeps_in_block = int(np.ceil(n_dft * self.f_s))
    self.new_sweeps_per_results = int(np.ceil(t_freq_est * self.f_s))
    self.phi_vec = np.zeros((self.sweeps_in_block, 1))
    self.f_est_vec = np.zeros(1)
    self.f_dft_est_vec = np.zeros(1)
    self.snr_vec = 0

    self.sweep_index = 0

def process(self, data):
    sweep = data
    
    if self.sweep_index == 0:
        delay_points = int(np.ceil(np.size(sweep) / self.D))
        self.data_s_d_mat = np.zeros((self.sweeps_in_block, delay_points), dtype="complex")
        self.data_s_d_mat[self.sweep_index, :] = self.downsample(sweep, self.D)

        out_data = None
    elif self.sweep_index < self.sweeps_in_block:
        self.data_s_d_mat[self.sweep_index, :] = self.iq_lp_filter_time(
            self.data_s_d_mat[self.sweep_index - 1, :], self.downsample(sweep, self.D)
        )

        temp_phi = self.unwrap_phase(
            self.phi_vec[self.sweep_index - 1],
            self.data_s_d_mat[self.sweep_index, :],
            self.data_s_d_mat[self.sweep_index - 1, :],
        )

        self.phi_vec[self.sweep_index] = self.unwrap_phase(
            self.phi_vec[self.sweep_index - 1],
            self.data_s_d_mat[self.sweep_index, :],
            self.data_s_d_mat[self.sweep_index - 1, :],
        )

        phi_filt = signal.lfilter(self.b, self.a, self.phi_vec, axis=0)

        out_data = {
            "phi_raw": self.phi_vec,
            "phi_filt": phi_filt,
            "power_spectrum": np.zeros(self.dft_points),
            "x_dft": np.linspace(self.f_low, self.f_high, self.dft_points),
            "f_dft_est_hist": self.f_dft_est_vec,
            "f_est_hist": self.f_est_vec,
            "f_dft_est": 0,
            "f_est": 0,
            "f_low": self.f_low,
            "f_high": self.f_high,
            "snr": 0,
            "lambda_p": self.lambda_p,
            "lambda_05": self.lambda_05,
            "dist_range": self.config.range_interval,
            "init_progress": round(100 * self.sweep_index / self.sweeps_in_block),
        }
    else:
        # Lowpass filter IQ data downsampled in distance points
        self.data_s_d_mat = np.roll(self.data_s_d_mat, -1, axis=0)
        self.data_s_d_mat[-1, :] = self.iq_lp_filter_time(
            self.data_s_d_mat[-2, :], self.downsample(sweep, self.D)
        )

        # Phase unwrapping of IQ data
        temp_phi = self.unwrap_phase(
            self.phi_vec[-1], self.data_s_d_mat[-1, :], self.data_s_d_mat[-2, :]
        )
        self.phi_vec = np.roll(self.phi_vec, -1, axis=0)
        self.phi_vec[-1] = temp_phi

        if np.mod(self.sweep_index, self.new_sweeps_per_results - 1) == 0:
            # Bandpass filter unwrapped data
            phi_filt_vec = signal.lfilter(self.b, self.a, self.phi_vec, axis=0)
            P, dft_est, _ = self.dft(self.downsample(phi_filt_vec, self.M))
            f_breath_est, _, snr, _ = self.breath_freq_est(P)

            self.f_est_vec = np.append(self.f_est_vec, f_breath_est)
            self.f_dft_est_vec = np.append(self.f_dft_est_vec, dft_est)
            self.snr_vec = np.append(self.snr_vec, snr)

            out_data = {
                "phi_raw": self.phi_vec,
                "phi_filt": phi_filt_vec,
                "power_spectrum": P,
                "x_dft": np.linspace(self.f_low, self.f_high, self.dft_points),
                "f_dft_est_hist": self.f_dft_est_vec,
                "f_est_hist": self.f_est_vec,
                "f_dft_est": dft_est,
                "f_est": f_breath_est,
                "f_low": self.f_low,
                "f_high": self.f_high,
                "snr": snr,
                "lambda_p": self.lambda_p,
                "lambda_05": self.lambda_05,
                "dist_range": self.config.range_interval,
                "init_progress": None,
            }
        else:
            out_data = None

    self.sweep_index += 1
    
    return out_data

def downsample(self, data, n):
    
    return data[::n]

def iq_lp_filter_time(self, state, new_data):
    return self.alpha_iq * state + (1 - self.alpha_iq) * new_data

def unwrap_phase(self, phase_lp, data_1, data_2):
    return phase_lp * self.alpha_phi + np.angle(np.mean(data_2 * np.conjugate(data_1)))

def dft(self, data):
    data = np.squeeze(data)
    n_vec = np.arange(data.size) * self.M
    dft = np.exp((2j * np.pi / self.f_s) * np.outer(self.dft_f_vec, n_vec))
    P = np.square(np.abs(np.matmul(dft, data)))
    idx_f = np.argmax(P)
    dft_est = self.dft_f_vec[idx_f]
    return P, dft_est, P[idx_f]

def noise_est(self, P):
    return np.mean(np.sort(P)[: (self.dft_points // 2) - 1])

def half_peak_frequency(self, P, f_est):
    idx_half = int(f_est / (2 * self.delta_f))
    if idx_half < self.f_low:
        return 0
    else:
        return (1 / self.delta_f) * (
            (self.dft_f_vec[idx_half + 1] - f_est / 2) * P[idx_half]
            + (f_est / 2 - self.dft_f_vec[idx_half]) * P[idx_half + 1]
        )

def breath_freq_est(self, P):
    f_idx = np.argmax(P)
    P_peak = P[f_idx]

    if self.interpolate:
        f_est, P_peak = self.freq_quad_interpolation(P)
    else:
        f_est = self.dft_f_vec[f_idx]

    P_half = self.half_peak_frequency(P, f_est)

    if P_peak < self.lambda_05 * P_half:
        f_est = f_est / 2
        P_peak = P_half

    if self.f_low < f_est < self.f_high and P_peak > self.lambda_p * self.noise_est(P):
        f_est_valid = True
    else:
        f_est_valid = False
        f_est = 0

    snr = P_peak / self.noise_est(P)
    print(f_est*60)
    return f_est, P_peak, snr, f_est_valid

def freq_quad_interpolation(self, P):
    f_idx = np.argmax(P)

    if 0 < f_idx < (P.size - 1) and P.size > 3:
        f_est = self.dft_f_vec[f_idx] + self.delta_f / 2 * (
            (np.log(P[f_idx + 1]) - np.log(P[f_idx - 1]))
            / (2 * np.log(P[f_idx]) - np.log(P[f_idx + 1]) - np.log(P[f_idx - 1]))
        )
        P_peak = P[f_idx] + np.exp(
            (1 / 8)
            * np.square(np.log(P[f_idx + 1]) - np.log(P[f_idx - 1]))
            / (2 * np.log(P[f_idx]) - np.log(P[f_idx + 1]) - np.log(P[f_idx - 1]))
        )

        if not (self.f_low < f_est < self.f_high):
            f_est = 0
    else:
        f_est = 0
        P_peak = 0

    return f_est, P_peak

class PGUpdater:
def init(self, sensor_config, processing_config, session_info):
self.config = sensor_config
args = et.a111.ExampleArgumentParser().parse_args()
et.utils.config_logging(args)
client = et.a111.Client(**et.a111.get_client_args(args))
client.squeeze = False

sensor_config = et.a111.IQServiceConfig()
sensor_config.sensor = args.sensors
sensor_config.range_interval = [0.2, 1.0]
sensor_config.profile = sensor_config.Profile.PROFILE_2
sensor_config.hw_accelerated_average_samples = 20
sensor_config.downsampling_factor = 2
sensor_config.update_rate=60
sensor_config.gain=0.6

session_info = client.setup_session(sensor_config)
interrupt_handler = et.utils.ExampleInterruptHandler()
print("Press Ctrl-C to end session")
pg_updater = PGUpdater(sensor_config, None, session_info)
pg_process = pg_processor_spoof.PGProcess(pg_updater)
pg_process.start()
client.start_session()
while not interrupt_handler.got_signal:
data_info, data = client.get_next()
proc=Processor

try:
    pg_process.put_data(data)
    out_data = proc(sensor_config, processing_config, session_info, calibration=None).process(data)
    data1 = proc(sensor_config, processing_config, session_info, calibration=None).downsample(out_data, n=2)
    P = proc(sensor_config, processing_config, session_info, calibration=None).dft(data1)
    f_est1 = proc(sensor_config, processing_config, session_info, calibration=None).breath_freq_est(P)
    if f_est1 > 0:
        s = "Latest frequency estimate: {:.2f} Hz | {:.0f} BPM".format(f_est1, f_est1 * 60)
        print(s)
except pg_processor_spoof.PGProccessDiedException:
    break

print("Disconnecting...")
pg_process.close()
client.disconnect()

Please resolve our issues, all three different errors. Our goal is to print the breath rate on the command prompt. Please help us in resolving the error.

Thanks!!

Hi,

The issues your are getting are issues in the script you have written.

You can run the sleep_breathing as a standalone application by running the following:
python -m acconeer.exptool.a111.algo.sleep_breathing

commented

C:\Users\nehab>python -m acconeer.exptool.a111.algo.sleep_breathing -u COM3
Press Ctrl-C to end session
14:45:08.587 | WARNING | MainProcess | acconeer.exptool.a111._clients.reg.client | successfully recovered from corrupt frame
14:45:08.660 | WARNING | MainProcess | acconeer.exptool.a111._clients.reg.client | successfully recovered from corrupt frame
14:45:08.762 | WARNING | MainProcess | acconeer.exptool.a111._clients.reg.client | successfully recovered from corrupt frame
14:45:09.163 | WARNING | MainProcess | acconeer.exptool.a111._clients.reg.client | successfully recovered from corrupt frame
14:45:09.237 | WARNING | MainProcess | acconeer.exptool.a111._clients.reg.client | successfully recovered from corrupt frame
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1776.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1776.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 86, in run_code
exec(code, run_globals)
File "C:\Users\nehab\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\acconeer\exptool\a111\algo\sleep_breathing_main
.py", line 9, in
main(module_info)
File "C:\Users\nehab\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\acconeer\exptool\a111\algo_standalone_main.py", line 35, in main
info, sweep = client.get_next()
File "C:\Users\nehab\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\acconeer\exptool\a111_clients\client.py", line 143, in get_next
return self.subclient.get_next()
File "C:\Users\nehab\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\acconeer\exptool\a111_clients\base.py", line 158, in get_next
return self._get_next()
File "C:\Users\nehab\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\acconeer\exptool\a111_clients\reg\client.py", line 259, in _get_next
packet = self._recv_packet(allow_recovery_skip=True)
File "C:\Users\nehab\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\acconeer\exptool\a111_clients\reg\client.py", line 402, in _recv_packet
raise ClientError("got invalid frame and could not recover")
acconeer.exptool.a111._clients.base.ClientError: got invalid frame and could not recover

Hi,

To repeat myself: make sure you have the latest SW on the XM112 and the latest ET.

Try resetting the module before starting the application. Try by pressing the reset button and also by unplugging the device.

Have you made any modifications to the algorithm?

commented

Hey that's fine.. but we need to write a single script to do all the required task and run the script on start up when connected to raspberry Pi.. so how to combine all the scripts in sleep_breathing file into a single script.

Hi,

I don't see any reason for you to add everything to one script. You should be able to install/transfer the files to the Raspberry PI as is. All modifications done is your responsibility.

commented

hey may i know how to run the module on raspberry pi, we have installed acconeer exploration tool on raspberry pi using command. Now we need to run the module!!

Hi,

You should be able to use the same steps for running XM112/XB112 on RPi as when running on a Ubuntu laptop.

commented

Hey, I have written code to measure heart rate but the accuracy is low. So i need to know is there any calibration to do for the sensor. If yes, how to calibrate let me know the step. If no, how to improve the accuracy.
Thanks regards,
Neha B

Hi,

We have no algorithm for heart rate measurement.

For the future, please close issues when solved and open new issues for new questions.