Split the Python application into a recording part and a visualiser part. Add matplotlib for creating a 3D scatter plot.

This commit is contained in:
HellaJanssen 2025-06-03 18:51:05 +02:00
parent 2a50334473
commit cccc73ba71
5 changed files with 113 additions and 175 deletions

2
.gitignore vendored
View file

@ -194,4 +194,4 @@ cython_debug/
.cursorindexingignore
# Project specific
sensor_data.bin
sensor_recording.bin

View file

@ -4,14 +4,8 @@ verify_ssl = true
name = "pypi"
[packages]
numpy = "*"
scipy = "*"
pyserial = "*"
pymmwave = "*"
pyqtgraph = "*"
pyside6 = "*"
matplotlib = "*"
pyqt5 = "*"
[dev-packages]

166
Pipfile.lock generated
View file

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "b640a95abf45b1c849908790d83bba056b5090f594b378c220dd83eb80a7383c"
"sha256": "d229dbac1fe37f1d8e0763868a9de994be21c0ecf18cfc716da2ac5fa127446d"
},
"pipfile-spec": 6,
"requires": {
@ -321,7 +321,6 @@
"sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de",
"sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==2.2.6"
},
@ -420,14 +419,6 @@
"markers": "python_version >= '3.9'",
"version": "==11.2.1"
},
"pymmwave": {
"hashes": [
"sha256:d622466271beeb3875ed8961589ae0bcb45e00134baec87bff46d49c501222eb"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==1.1.2"
},
"pyparsing": {
"hashes": [
"sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf",
@ -436,63 +427,6 @@
"markers": "python_version >= '3.9'",
"version": "==3.2.3"
},
"pyqt5": {
"hashes": [
"sha256:6cd75628f6e732b1ffcfe709ab833a0716c0445d7aec8046a48d5843352becb6",
"sha256:76be0322ceda5deecd1708a8d628e698089a1cea80d1a49d242a6d579a40babd",
"sha256:bdde598a3bb95022131a5c9ea62e0a96bd6fb28932cc1619fd7ba211531b7517",
"sha256:c8b03dd9380bb13c804f0bdb0f4956067f281785b5e12303d529f0462f9afdc2",
"sha256:cd672a6738d1ae33ef7d9efa8e6cb0a1525ecf53ec86da80a9e1b6ec38c8d0f1",
"sha256:fda45743ebb4a27b4b1a51c6d8ef455c4c1b5d610c90d2934c7802b5c1557c52"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==5.15.11"
},
"pyqt5-qt5": {
"hashes": [
"sha256:b018f75d1cc61146396fa5af14da1db77c5d6318030e5e366f09ffdf7bd358d8",
"sha256:b68628f9b8261156f91d2f72ebc8dfb28697c4b83549245d9a68195bd2d74f0c",
"sha256:d8b8094108e748b4bbd315737cfed81291d2d228de43278f0b8bd7d2b808d2b9"
],
"version": "==5.15.17"
},
"pyqt5-sip": {
"hashes": [
"sha256:023466ae96f72fbb8419b44c3f97475de6642fa5632520d0f50fc1a52a3e8200",
"sha256:0c75d28b8282be3c1d7dbc76950d6e6eba1e334783224e9b9835ce1a9c64f482",
"sha256:2c912807dd638644168ea8c7a447bfd9d85a19471b98c2c588c4d2e911c09b0a",
"sha256:2f2a8dcc7626fe0da73a0918e05ce2460c7a14ddc946049310e6e35052105434",
"sha256:32b03e7e77ecd7b4119eba486b0706fa59b490bcceb585f9b6ddec8a582082db",
"sha256:351beab964a19f5671b2a3e816ecf4d3543a99a7e0650f88a947fea251a7589f",
"sha256:419b9027e92b0b707632c370cfc6dc1f3b43c6313242fc4db57a537029bd179c",
"sha256:4a92478d6808040fbe614bb61500fbb3f19f72714b99369ec28d26a7e3494115",
"sha256:54c31de7706d8a9a8c0fc3ea2c70468aba54b027d4974803f8eace9c22aad41c",
"sha256:5b6c734f4ad28f3defac4890ed747d391d246af279200935d49953bc7d915b8c",
"sha256:672c209d05661fab8e17607c193bf43991d268a1eefbc2c4551fbf30fd8bb2ca",
"sha256:682dadcdbd2239af9fdc0c0628e2776b820e128bec88b49b8d692fe682f90b4f",
"sha256:71514a7d43b44faa1d65a74ad2c5da92c03a251bdc749f009c313f06cceacc9a",
"sha256:855e8f5787d57e26a48d8c3de1220a8e92ab83be8d73966deac62fdae03ea2f9",
"sha256:8c4bc535bae0dfa764e8534e893619fe843ce5a2e25f901c439bcb960114f686",
"sha256:b0ff280b28813e9bfd3a4de99490739fc29b776dc48f1c849caca7239a10fc8b",
"sha256:c7a7ff355e369616b6bcb41d45b742327c104b2bf1674ec79b8d67f8f2fa9543",
"sha256:d65a9c1b4cbbd8e856254609f56e897d2cb5c903f77b75fb720cb3a32c76b92b",
"sha256:ea08341c8a5da00c81df0d689ecd4ee47a95e1ecad9e362581c92513f2068005",
"sha256:ec47914cc751608e587c1c2fdabeaf4af7fdc28b9f62796c583bea01c1a1aa3e",
"sha256:fb565469d08dcb0a427def0c45e722323beb62db79454260482b6948bfd52d47"
],
"markers": "python_version >= '3.9'",
"version": "==12.17.0"
},
"pyqtgraph": {
"hashes": [
"sha256:64f84f1935c6996d0e09b1ee66fe478a7771e3ca6f3aaa05f00f6e068321d9e3",
"sha256:7754edbefb6c367fa0dfb176e2d0610da3ada20aa7a5318516c74af5fb72bf7a"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==0.13.7"
},
"pyserial": {
"hashes": [
"sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb",
@ -501,40 +435,6 @@
"index": "pypi",
"version": "==3.5"
},
"pyside6": {
"hashes": [
"sha256:0103e5d161696db40d75bfbf4e4b7d4f3372903c1b400c4e3379377b62c50290",
"sha256:09239d1b808f18efccd3803db874d683917efcdebfdf0e8dec449cf50e74e7aa",
"sha256:1a176409dd0dd12b72d2c78b776e5051f569071ec52b7aaadd0a5b3333493c24",
"sha256:846fbccf0b3501eb31cf0791a46e137615efba6ce540da2b426d79fa3e7762c4",
"sha256:b8f286a1bd143f3b2bdf08367b9362b13f469d26986c25700af9c4c68f79213e"
],
"index": "pypi",
"markers": "python_version < '3.14' and python_version >= '3.9'",
"version": "==6.9.0"
},
"pyside6-addons": {
"hashes": [
"sha256:260a56da59539f476c1635a3ff13591e10f1b04d92155c0617129bc53ca8b5f8",
"sha256:8cf54065b3d1b4698448fad825378a25c10ef52017d9dff48cead03200636d8d",
"sha256:98f9ad4b65820736e12d49c18db2e570eac63727407fbb59a62ac753e89dc201",
"sha256:d8a650644e0b9d1e7a092f6bcd11f25a63706d12f77d442b6ace75d346ab5d30",
"sha256:fc9dcd63a0ce7565f238cb11c44494435a50eb6cb72b8dbce3b709618989c3dc"
],
"markers": "python_version < '3.14' and python_version >= '3.9'",
"version": "==6.9.0"
},
"pyside6-essentials": {
"hashes": [
"sha256:45eaf7f17688d1991f39680dbfd3c41674f3cbb78f278aa10fe0b5f2f31c1989",
"sha256:69aedfad77119c5bec0005ca31d5620e9bac8ba5ae66c7389160530cfd698ed8",
"sha256:94a0096d6bb1d3e5cef29ca4a5366d0f229d42480fbb17aa25ad85d72b1b7947",
"sha256:b18e3e01b507e8a57481fe19792eb373d5f10a23a50702ce540da1435e722f39",
"sha256:d2dc45536f2269ad111991042e81257124f1cd1c9ed5ea778d7224fd65dc9e2b"
],
"markers": "python_version < '3.14' and python_version >= '3.9'",
"version": "==6.9.0"
},
"python-dateutil": {
"hashes": [
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
@ -543,70 +443,6 @@
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==2.9.0.post0"
},
"scipy": {
"hashes": [
"sha256:05dc6abcd105e1a29f95eada46d4a3f251743cfd7d3ae8ddb4088047f24ea477",
"sha256:06efcba926324df1696931a57a176c80848ccd67ce6ad020c810736bfd58eb1c",
"sha256:0a769105537aa07a69468a0eefcd121be52006db61cdd8cac8a0e68980bbb723",
"sha256:0bdd905264c0c9cfa74a4772cdb2070171790381a5c4d312c973382fc6eaf730",
"sha256:0ff17c0bb1cb32952c09217d8d1eed9b53d1463e5f1dd6052c7857f83127d539",
"sha256:14ed70039d182f411ffc74789a16df3835e05dc469b898233a245cdfd7f162cb",
"sha256:185cd3d6d05ca4b44a8f1595af87f9c372bb6acf9c808e99aa3e9aa03bd98cf6",
"sha256:18aaacb735ab38b38db42cb01f6b92a2d0d4b6aabefeb07f02849e47f8fb3594",
"sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92",
"sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82",
"sha256:271e3713e645149ea5ea3e97b57fdab61ce61333f97cfae392c28ba786f9bb49",
"sha256:2c620736bcc334782e24d173c0fdbb7590a0a436d2fdf39310a8902505008759",
"sha256:34716e281f181a02341ddeaad584205bd2fd3c242063bd3423d61ac259ca7eba",
"sha256:39cb9c62e471b1bb3750066ecc3a3f3052b37751c7c3dfd0fd7e48900ed52982",
"sha256:3ac07623267feb3ae308487c260ac684b32ea35fd81e12845039952f558047b8",
"sha256:3b0334816afb8b91dab859281b1b9786934392aa3d527cd847e41bb6f45bee65",
"sha256:40e54d5c7e7ebf1aa596c374c49fa3135f04648a0caabcb66c52884b943f02b4",
"sha256:50f9e62461c95d933d5c5ef4a1f2ebf9a2b4e83b0db374cb3f1de104d935922e",
"sha256:52092bc0472cfd17df49ff17e70624345efece4e1a12b23783a1ac59a1b728ed",
"sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c",
"sha256:5e721fed53187e71d0ccf382b6bf977644c533e506c4d33c3fb24de89f5c3ed5",
"sha256:6487aa99c2a3d509a5227d9a5e889ff05830a06b2ce08ec30df6d79db5fcd5c5",
"sha256:6ac6310fdbfb7aa6612408bd2f07295bcbd3fda00d2d702178434751fe48e019",
"sha256:6cfd56fc1a8e53f6e89ba3a7a7251f7396412d655bca2aa5611c8ec9a6784a1e",
"sha256:6db907c7368e3092e24919b5e31c76998b0ce1684d51a90943cb0ed1b4ffd6c1",
"sha256:721d6b4ef5dc82ca8968c25b111e307083d7ca9091bc38163fb89243e85e3889",
"sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca",
"sha256:79167bba085c31f38603e11a267d862957cbb3ce018d8b38f79ac043bc92d825",
"sha256:795c46999bae845966368a3c013e0e00947932d68e235702b5c3f6ea799aa8c9",
"sha256:7e11270a000969409d37ed399585ee530b9ef6aa99d50c019de4cb01e8e54e62",
"sha256:8c9ed3ba2c8a2ce098163a9bdb26f891746d02136995df25227a20e71c396ebb",
"sha256:993439ce220d25e3696d1b23b233dd010169b62f6456488567e830654ee37a6b",
"sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13",
"sha256:9db984639887e3dffb3928d118145ffe40eff2fa40cb241a306ec57c219ebbbb",
"sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40",
"sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c",
"sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253",
"sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb",
"sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f",
"sha256:b90ab29d0c37ec9bf55424c064312930ca5f4bde15ee8619ee44e69319aab163",
"sha256:c05045d8b9bfd807ee1b9f38761993297b10b245f012b11b13b91ba8945f7e45",
"sha256:c9deabd6d547aee2c9a81dee6cc96c6d7e9a9b1953f74850c179f91fdc729cb7",
"sha256:dde4fc32993071ac0c7dd2d82569e544f0bdaff66269cb475e0f369adad13f11",
"sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf",
"sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e",
"sha256:f77f853d584e72e874d87357ad70f44b437331507d1c311457bed8ed2b956126"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==1.15.3"
},
"shiboken6": {
"hashes": [
"sha256:121ea290ed1afa5ad6abf690b377612693436292b69c61b0f8e10b1f0850f935",
"sha256:24f53857458881b54798d7e35704611d07f6b6885bcdf80f13a4c8bb485b8df2",
"sha256:3f585caae5b814a7e23308db0a077355a7dc20c34d58ca4c339ff7625e9a1936",
"sha256:b61579b90bf9c53ecc174085a69429166dfe57a0b8b894f933d1281af9df6568",
"sha256:c4d8e3a5907154ac4789e52c77957db95bcf584238c244d7743cb39e9b66dd26"
],
"markers": "python_version < '3.14' and python_version >= '3.9'",
"version": "==6.9.0"
},
"six": {
"hashes": [
"sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274",

94
recorder.py Normal file
View file

@ -0,0 +1,94 @@
import serial
import time
import datetime
import pickle
from pathlib import Path
from parser_mmw_demo import parser_one_mmw_demo_output_packet
def configure_sensor(config_file: Path, config_device: serial.Serial):
with config_file.open(mode="rt", encoding="utf-8") as config_fp:
for line in config_fp:
line = line.rstrip("\r\n")
print(f"[CONFIG] writing: '{line}'")
config_device.write((line + "\n").encode())
time.sleep(0.01)
# parser_one_mmw_demo_output_packet extracts only one complete frame at a time
# so call this in a loop till end of file
def parse_frames(data_device: serial.Serial, record_file: Path = Path("sensor_recording.bin")):
sensor_data = bytearray()
bytes_parsed = 0
with record_file.open(mode="wb") as fp:
while True:
read_data = data_device.read(256)
sensor_data += bytearray(read_data)
# parser_one_mmw_demo_output_packet function already prints the
# parsed data to stdio. So showcasing only saving the data to arrays
# here for further custom processing
parser_result, \
headerStartIndex, \
totalPacketNumBytes, \
numDetObj, \
numTlv, \
subFrameNumber, \
detectedX_array, \
detectedY_array, \
detectedZ_array, \
detectedV_array, \
detectedRange_array, \
detectedAzimuth_array, \
detectedElevation_array, \
detectedSNR_array, \
detectedNoise_array = parser_one_mmw_demo_output_packet(sensor_data[bytes_parsed::1], len(sensor_data) - bytes_parsed)
pickle.dump({
"timestamp": datetime.now(),
"parser_result": parser_result,
"header_start_index": headerStartIndex,
"total_packet_size": totalPacketNumBytes,
"detected_objects": numDetObj,
"tlv_count": numTlv,
"sub_frame_number": subFrameNumber,
"detected_points": (detectedX_array,
detectedY_array,
detectedZ_array,
detectedV_array,
detectedRange_array,
detectedAzimuth_array,
detectedElevation_array,
detectedSNR_array,
detectedNoise_array),
}, fp)
# Check the parser result
print ("Parser result: ", parser_result)
if (parser_result == 0):
bytes_parsed += (headerStartIndex+totalPacketNumBytes)
print("totalBytesParsed: ", bytes_parsed)
def main():
config_device = serial.Serial('/dev/ttyACM0', 115200)
data_device = serial.Serial('/dev/ttyACM1', 921600)
configure_sensor(Path("hedgehog.cfg"), config_device)
try:
parse_frames(data_device)
except:
config_device.write("sensorStop\n".encode())
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
exit(0)

20
test.py
View file

@ -2,6 +2,7 @@ import serial
import time
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from parser_mmw_demo import parser_one_mmw_demo_output_packet
@ -44,7 +45,13 @@ CLIport, Dataport = serialConfig(configFileName) # Enable when reading from sens
def parse_frames():
ax = fig.add_subplot(projection='3d')
ax = fig.add_subplot(projection="3d")
# making the plot axis constant
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_zlim(0, 1)
plt.show()
sensor_data = bytearray()
@ -76,8 +83,15 @@ def parse_frames():
detectedNoise_array = parser_one_mmw_demo_output_packet(sensor_data[bytes_parsed::1], len(sensor_data) - bytes_parsed)
ax.clear()
# Setting axis labels
ax.set_xlabel("X label")
ax.set_ylabel("Y label")
ax.set_zlabel("Z label")
ax.set_autoscale_on(False)
ax.scatter(detectedX_array, detectedY_array, detectedZ_array)
plt.pause(0.1)
plt.pause(0.01)
# Check the parser result
print ("Parser result: ", parser_result)
@ -85,7 +99,7 @@ def parse_frames():
bytes_parsed += (headerStartIndex+totalPacketNumBytes)
print("totalBytesParsed: ", bytes_parsed)
else:
bytes_parsed += 1
# bytes_parsed += 1
continue
if __name__ == "__main__":