Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
AP-S 2020 - PyRaTk
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
DELTA
DELTA Low-Cost 5.8GHz FMCW Radar PCB
AP-S 2020 Software
AP-S 2020 - PyRaTk
Commits
61d54c8a
Commit
61d54c8a
authored
4 years ago
by
Merlo, Jason
Browse files
Options
Downloads
Patches
Plain Diff
Added mcdaq and reformateed daq class
parent
b3f403fa
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
pyratk/acquisition/daq.py
+12
-123
12 additions, 123 deletions
pyratk/acquisition/daq.py
pyratk/acquisition/virtual_daq.py
+0
-24
0 additions, 24 deletions
pyratk/acquisition/virtual_daq.py
pyratk/widgets/fft_widget.py
+6
-4
6 additions, 4 deletions
pyratk/widgets/fft_widget.py
with
18 additions
and
151 deletions
pyratk/acquisition/daq.py
+
12
−
123
View file @
61d54c8a
...
...
@@ -11,12 +11,6 @@ Maintainer: Jason Merlo (merlojas@msu.edu)
Dependencies: nidaqmx, random, Threading, time, numpy
"""
try
:
import
nidaqmx
# Used for NI-DAQ hardware
from
nidaqmx
import
stream_readers
except
ImportError
:
print
(
'
Warning: nidaqmx module not imported
'
)
import
threading
# Used for creating thread and sync events
import
time
import
numpy
as
np
...
...
@@ -32,78 +26,25 @@ class DAQ(QtCore.QThread):
data_available_signal
=
QtCore
.
pyqtSignal
(
tuple
)
reset_signal
=
QtCore
.
pyqtSignal
()
# required for VirtualDAQ
def
__init__
(
self
,
daq_type
=
"
NI-DAQ
"
,
sample_rate
=
44100
,
sample_chunk_size
=
4096
,
# NI-DAQ specific
dev_string
=
"
Dev1/ai0:7
"
,
sample_mode
=
nidaqmx
.
constants
.
AcquisitionType
.
FINITE
):
def
__init__
(
self
,
sample_rate
=
50000
,
sample_chunk_size
=
50000
,
num_channels
=
8
):
"""
Create sampling task on DAQ and opens I & Q channels for radars.
Emits a signal when new data is available.
arguments:
dev_string -- device and ports to initialize (default:
"
Dev1/ai0:7
"
)
sample_rate -- frequency in Hz to sample at (default: 44100)
sample_mode -- finite or continuous acquisition (default: finite)
sample_chunk_size -- size of chunk to read (default/max: 4095)
"""
super
().
__init__
()
# Copy member data
# General arguments
self
.
sample_rate
=
sample_rate
self
.
sample_chunk_size
=
sample_chunk_size
self
.
num_channels
=
num_channels
self
.
update_period
=
sample_chunk_size
/
sample_rate
self
.
daq_type
=
daq_type
self
.
paused
=
True
self
.
running
=
False
self
.
sample_num
=
0
# Device specific arguments
if
self
.
daq_type
==
"
NI-DAQ
"
:
self
.
sample_mode
=
sample_mode
self
.
dev_string
=
dev_string
# Get number of channels to sample
if
self
.
dev_string
[
-
2
]
==
'
:
'
:
self
.
num_channels
=
int
(
self
.
dev_string
[
-
1
])
-
int
(
self
.
dev_string
[
-
3
])
+
1
else
:
self
.
num_channels
=
int
(
self
.
dev_string
[
-
1
])
+
1
# Create new sampling task
try
:
# Try to create sampling task
self
.
task
=
nidaqmx
.
Task
()
self
.
task
.
ai_channels
.
add_ai_voltage_chan
(
dev_string
)
self
.
task
.
timing
.
cfg_samp_clk_timing
(
sample_rate
,
sample_mode
=
sample_mode
,
samps_per_chan
=
sample_chunk_size
)
self
.
in_stream
=
\
stream_readers
.
AnalogMultiChannelReader
(
self
.
task
.
in_stream
)
except
nidaqmx
.
_lib
.
DaqNotFoundError
:
# On failure (ex. on mac/linux) generate random data for
# development purposes
# TODO: switch to PyDAQmx for mac/linux
# TODO: is there any reason to keep nidaqmx for windows?
# TODO: try performance comparison
self
.
daq_type
=
"
FakeDAQ
"
print
(
"
=
"
*
80
)
print
(
"
Warning: Using fake data. nidaqmx is not
"
"
supported on this platform.
"
)
print
(
"
=
"
*
80
)
except
nidaqmx
.
errors
.
DaqError
as
e
:
print
(
e
)
self
.
daq_type
=
"
FakeDAQ
"
print
(
"
=
"
*
80
)
print
(
"
Warning: Using fake data. DAQ could not be detected.
"
)
print
(
"
=
"
*
80
)
elif
self
.
daq_type
==
"
PyAudioDAQ
"
:
pass
# TODO insert pyaudio support here
# Create data member to store samples
self
.
data
=
np
.
empty
((
self
.
num_channels
,
self
.
sample_chunk_size
),)
...
...
@@ -112,69 +53,9 @@ class DAQ(QtCore.QThread):
shape
=
(
self
.
num_channels
,
self
.
sample_chunk_size
)
self
.
ts_buffer
=
TimeSeries
(
length
,
shape
)
# === SAMPLING ======================================================
def
sample_loop
(
self
):
"""
Call get_samples forever.
"""
while
self
.
running
:
if
self
.
paused
:
# warning('(daq.py) daq paused...')
time
.
sleep
(
0.1
)
# sleep 100 ms
else
:
self
.
get_samples
()
print
(
"
Sampling thread stopped.
"
)
def
get_samples
(
self
):
"""
Read device sample buffers returning the specified sample size.
"""
if
self
.
daq_type
==
"
FakeDAQ
"
:
sleep_time
=
self
.
sample_chunk_size
/
self
.
sample_rate
self
.
data
=
np
.
random
.
randn
(
self
.
num_channels
,
self
.
sample_chunk_size
)
*
0.001
+
\
np
.
random
.
randn
(
1
)
*
0.001
+
0.01
time
.
sleep
(
sleep_time
)
else
:
try
:
read_all
=
nidaqmx
.
constants
.
READ_ALL_AVAILABLE
self
.
in_stream
.
read_many_sample
(
self
.
data
,
number_of_samples_per_channel
=
read_all
,
timeout
=
1.0
)
# print('received update')
except
nidaqmx
.
errors
.
DaqError
as
err
:
print
(
"
DAQ exception caught: {0}
\n
"
.
format
(
err
))
new_data
=
(
self
.
data
,
self
.
sample_num
)
# Set the update event to True once data is read in
self
.
data_available_signal
.
emit
(
new_data
)
self
.
ts_buffer
.
append
(
self
.
data
)
# Incriment sample number
self
.
sample_num
+=
1
# === CONTROL =======================================================
def
close
(
self
):
print
(
"
Stopping sampling thread...
"
)
self
.
running
=
False
if
self
.
daq_type
==
"
NI-DAQ
"
and
hasattr
(
self
,
'
task
'
):
self
.
task
.
close
()
# Close nidaq gracefully
if
self
.
t_sampling
.
is_alive
():
try
:
self
.
t_sampling
.
join
()
except
Exception
as
e
:
print
(
"
Error closing sampling thread:
"
,
e
)
def
run
(
self
):
# Spawn sampling thread
self
.
running
=
True
self
.
t_sampling
=
threading
.
Thread
(
target
=
self
.
sample_loop
)
try
:
if
not
self
.
t_sampling
.
is_alive
():
print
(
'
Staring sampling thread
'
)
self
.
t_sampling
.
start
()
# self.paused = False
except
RuntimeError
as
e
:
print
(
'
Error starting sampling thread:
'
,
e
)
def
pause
(
self
):
self
.
paused
=
True
...
...
@@ -183,6 +64,14 @@ class DAQ(QtCore.QThread):
self
.
ts_buffer
.
clear
()
self
.
sample_num
=
0
def
start
(
self
):
"""
Begin sampling process on DAQ.
To be implemented by child classes.
"""
pass
# === PROPERTIES ====================================================
@property
def
type
(
self
):
...
...
This diff is collapsed.
Click to expand it.
pyratk/acquisition/virtual_daq.py
+
0
−
24
View file @
61d54c8a
...
...
@@ -23,30 +23,6 @@ class VirtualDAQ(daq.DAQ):
def
__init__
(
self
):
"""
Create virtual DAQ object to play back recording (hdf5 dataset).
"""
super
().
__init__
()
# Attributes
self
.
sample_rate
=
None
self
.
sample_chunk_size
=
None
self
.
daq_type
=
None
self
.
num_channels
=
None
# start paused if no dataset is selected
self
.
paused
=
True
# Fake sampler period
self
.
sample_period
=
None
# Create data member to store samples
self
.
data
=
None
self
.
ds
=
None
# create member data to store trajectory samples for ground truth
self
.
ts
=
None
# Current time index of recording
self
.
sample_index
=
0
# Reset/load button sample thread locking
# self.reset_lock = threading.Event()
self
.
t_sampling
=
threading
.
Thread
(
target
=
self
.
sample_loop
)
def
load_dataset
(
self
,
ds
):
"""
Select dataset to read from and loads attributes.
"""
...
...
This diff is collapsed.
Click to expand it.
pyratk/widgets/fft_widget.py
+
6
−
4
View file @
61d54c8a
...
...
@@ -13,7 +13,8 @@ import time # Used for FPS calculations
class
FftWidget
(
pg
.
GraphicsLayoutWidget
):
def
__init__
(
self
,
radar
,
vmax_len
=
100
,
show_max_plot
=
False
):
def
__init__
(
self
,
radar
,
vmax_len
=
100
,
show_max_plot
=
False
,
fft_yrange
=
[
-
100
,
100
],
fft_xrange
=
[
-
5000
,
5000
]):
super
(
FftWidget
,
self
).
__init__
()
# Copy arguments to member variables
...
...
@@ -50,8 +51,8 @@ class FftWidget(pg.GraphicsLayoutWidget):
self
.
nextRow
()
# Calculate reasonable ranges for FFT peak outputs
fft_xrange
=
[
-
50
/
self
.
radar
.
bin_size
,
50
/
self
.
radar
.
bin_size
]
fft_yrange
=
[
-
100
,
0
]
#
fft_xrange = [-50 / self.radar.bin_size, 50 / self.radar.bin_size]
#
fft_yrange = [-100, 0]
# Add FFT plot
self
.
fft_plot
=
self
.
addPlot
()
...
...
@@ -63,7 +64,8 @@ class FftWidget(pg.GraphicsLayoutWidget):
self
.
fft_plot
.
setRange
(
disableAutoRange
=
True
,
xRange
=
fft_xrange
,
yRange
=
fft_yrange
)
self
.
fft_plot
.
setLimits
(
xMin
=
fft_xrange
[
0
],
xMax
=
fft_xrange
[
1
],
yMin
=-
80
,
yMax
=
0
)
xMin
=
fft_xrange
[
0
],
xMax
=
fft_xrange
[
1
],
yMin
=
fft_yrange
[
0
],
yMax
=
fft_yrange
[
1
])
self
.
fft_pw
=
self
.
fft_plot
.
plot
()
self
.
fft_max_freq_line
=
pg
.
InfiniteLine
(
angle
=
90
,
movable
=
False
)
self
.
fft_max_pwr_line
=
pg
.
InfiniteLine
(
angle
=
0
,
movable
=
False
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment